Debug: Colima Mati Setiap Kali Mac Studio Restart

Beberapa minggu setelah saya pasang Mac Studio sebagai server rumahan untuk menjalankan stack Docker (nginx, database, PHP untuk beberapa aplikasi termasuk situs ini), saya menemukan pola yang cukup menyebalkan: setiap kali mesin ini saya restart, seluruh container gagal menyala lagi secara otomatis. Padahal saya sudah mendaftarkan job launchd supaya Colima — yang saya pakai sebagai runtime Docker di macOS — ikut start otomatis saat boot. Di atas kertas semuanya benar, tapi di lapangan situs saya selalu down setiap habis restart, sampai saya login manual dan menyalakan ulang semuanya satu per satu.

Mencari akar masalah

Setelah beberapa kali kejadian berulang, saya mulai curiga masalahnya bukan di konfigurasi launchd itu sendiri, tapi di cara Colima start ulang. Colima jalan di atas VM ringan (mode vz bawaan macOS), dan VM itu punya file PID sendiri untuk menandai bahwa prosesnya sedang hidup.

Ternyata saat host di-restart, VM ini ikut mati paksa bareng shutdown, tanpa sempat membersihkan file PID miliknya. Begitu mesin boot lagi, Colima membaca file PID basi tersebut untuk mengecek apakah instance lama masih hidup. Masalahnya, nomor PID itu bersifat terbatas dan didaur ulang oleh sistem operasi — jadi PID basi itu kebetulan cocok dengan proses lain yang sama sekali tidak berhubungan. Colima pun mengira dirinya sudah berjalan, bingung, dan menolak start dengan pesan error yang tidak jelas asal masalahnya.

Yang membuat ini makin parah: job launchd untuk Colima saya konfigurasi untuk retry hanya kalau proses berhenti dengan clean exit. Kegagalan gara-gara bentrok PID ini tidak dianggap clean exit oleh launchd, jadi dia diam saja — tidak ada percobaan ulang otomatis. Efeknya domino: nginx dan PHP saya jalan di dalam container-container itu, jadi begitu Colima gagal start, seluruh situs ikut down sampai saya intervensi manual.

Solusi lapis pertama: bersihkan PID basi

Perbaikan pertama yang saya buat cukup sederhana: sebuah wrapper script kecil yang dipanggil sebelum Colima asli dijalankan. Script ini mengecek dulu apakah PID yang tercatat di file lama itu benar-benar milik proses Colima/VM yang masih hidup. Kalau ternyata bukan (alias basi/recycled), script menghapus file PID itu dulu, baru menjalankan Colima yang sebenarnya. Dengan begitu Colima tidak lagi tertipu oleh PID yang salah kaprah.

Dua lapis pertahanan tambahan

Karena saya sadar penyebab kegagalan bisa datang dari sisi lain di masa depan, saya tidak berhenti di satu fix. Saya menambahkan dua lapis lagi:

  • Retry policy launchd yang lebih longgar. Saya ubah konfigurasi jadi retry terus tanpa syarat clean-exit, dengan jeda singkat antar percobaan. Jadi apa pun jenis kegagalannya, launchd akan tetap mencoba lagi, bukan diam menyerah.
  • Watchdog terpisah. Sebuah script yang jalan berkala tiap beberapa menit, mengecek seluruh rantai dari bawah ke atas: apakah VM Colima hidup, apakah container-container utama jalan, apakah nginx lokal merespons, dan apakah situs publik bisa diakses. Kalau ada satu lapisan yang rusak, watchdog otomatis mencoba menyembuhkannya, dan mencatat log setiap kali benar-benar melakukan tindakan perbaikan — supaya saya bisa audit belakangan tindakan apa saja yang pernah diambil otomatis.

Saya uji langsung dengan sengaja mematikan salah satu container secara manual. Watchdog mendeteksinya dalam hitungan menit, menjalankan ulang container tersebut, dan situs pulih dari error ke normal tanpa saya sentuh apa pun.

Pelajaran yang saya bawa

Autostart yang "sudah didaftarkan" tidak sama dengan autostart yang benar-benar bisa diandalkan. Yang saya pelajari: jangan percaya begitu saja pada mekanisme retry bawaan tanpa memahami syarat di baliknya (di kasus ini, syarat clean-exit yang ternyata tidak terpenuhi), dan selalu siapkan lapisan pemantauan independen yang mengecek hasil akhir yang benar-benar dipedulikan pengguna — situs bisa diakses atau tidak — bukan cuma status satu proses saja.