# Runbook Insiden Produksi (Production Incident Runbook) Panduan operasional bagi engineer untuk mendiagnosis, menstabilkan, dan memulihkan sistem saat terjadi insiden di server produksi Hostinger KVM 2. --- ## 1. Langkah Pertama: Triage Cepat (Quick Triage Checklist) Saat menerima laporan error atau notifikasi downtime: 1. **Cek Responsibilitas Server**: ```bash ssh root@ uptime # Periksa load average (harus di bawah 2.0 untuk dual-core) free -m # Periksa RAM bebas dan swap usage df -h # Periksa kapasitas disk NVMe (pastikan / tidak 100%) ``` 2. **Cek Status Kontainer**: ```bash podman ps --all # Perhatikan status: apakah ada container yang 'Exited' atau 'Restarting' ``` 3. **Cek Healthcheck Endpoint Backend**: ```bash curl -i http://127.0.0.1:3004/health curl -i http://127.0.0.1:3004/ready ``` --- ## 2. Penanganan Insiden Khusus ### Insiden 1: Lonjakan Memori Tinggi / OOM Kills - **Gejala**: Salah satu container (misal `keluargamart-b2b` atau `backend`) restart mendadak dengan exit code `137` (SIGKILL / OOM). - **Diagnosis**: ```bash dmesg -T | grep -i oom podman stats --no-stream ``` - **Mitigasi**: 1. Periksa batas memory limits pada `compose.prod.yml`. 2. Untuk Nuxt B2B, pastikan `NODE_OPTIONS="--max-old-space-size=256"` aktif. 3. Untuk Go backend, pastikan `GOMEMLIMIT=512MiB` aktif. 4. Bersihkan memori cache Linux jika sangat mendesak: ```bash sync; echo 3 > /proc/sys/vm/drop_caches ``` ### Insiden 2: CPU Saturation (Load Average > 4.0) - **Gejala**: Response time API melambat drastis (>3000ms), request timeout. - **Diagnosis**: ```bash top -b -n 1 | head -n 20 ``` - **Mitigasi**: 1. Jika penyebabnya adalah query PostgreSQL yang lambat (*long-running query*): ```bash podman exec -it keluargamart-postgres psql -U erp -d erp -c " SELECT pid, now() - query_start AS duration, query FROM pg_stat_activity WHERE state = 'active' AND (now() - query_start) > interval '10 seconds'; " ``` 2. Hentikan query yang tersangkut: ```bash podman exec -it keluargamart-postgres psql -U erp -d erp -c "SELECT pg_cancel_backend();" ``` ### Insiden 3: Cloudflare Tunnel Error 502 / Connection Refused - **Gejala**: Akses ke `https://erp-km.trl.my.id` atau `https://pos-km.trl.my.id` menampilkan halaman Cloudflare 502 Bad Gateway. - **Diagnosis**: ```bash journalctl -u cloudflared -n 50 --no-pager curl -I http://127.0.0.1:3001 ``` - **Mitigasi**: 1. Jika curl lokal gagal: periksa apakah container `keluargamart-erp` berjalan dan port mapping-nya `127.0.0.1:3001:8080`. 2. Periksa log Nginx entrypoint: ```bash podman logs --tail 50 keluargamart-erp ``` 3. Jika DNS resolver Nginx stale (backend berubah IP internal): restart container ERP: ```bash podman restart keluargamart-erp ``` ### Insiden 4: Disk NVMe Hampir Penuh (>85%) - **Gejala**: Error `write: no space left on device` saat upload file atau restart container. - **Mitigasi**: 1. Hapus image container lama / dangling: ```bash podman image prune -a -f --filter "until=72h" ``` 2. Bersihkan log container lama (jika ada yang tidak terotasi): ```bash podman container prune -f ``` 3. Periksa ukuran direktori terbesar: ```bash du -sh /var/lib/containers/* | sort -h ```