Strategi Backup untuk Aplikasi Self-Hosted

Kalau Anda meng-host aplikasi sendiri — entah itu Laravel di belakang Docker, database MariaDB/Postgres, atau stack lain di server pribadi — cepat atau lambat pertanyaan ini akan muncul: kalau server ini rusak total besok pagi, berapa lama saya bisa hidup lagi, dan berapa banyak data yang hilang? Buat saya yang sehari-hari kerja di sistem klinik dan rumah sakit, pertanyaan ini bukan sekadar teori. Data yang hilang di sistem seperti itu bukan cuma soal ketidaknyamanan, tapi bisa menyangkut rekam yang tidak bisa digantikan. Tapi prinsipnya sama saja untuk aplikasi self-hosted apa pun: backup itu murah untuk disiapkan, dan sangat mahal untuk disesali kalau ternyata tidak bisa dipakai saat dibutuhkan.

Backup terjadwal: cakup semua yang membuat aplikasi hidup

Godaan paling umum adalah hanya mem-backup database, karena itu yang paling terasa "berharga". Padahal aplikasi modern biasanya punya tiga lapis yang sama-sama perlu dicadangkan: database itu sendiri, file storage (upload pengguna, hasil generate, dokumen), dan konfigurasi/environment (file .env, docker-compose, kunci enkripsi, cron jobs). Kehilangan salah satu saja bisa membuat dua lainnya tidak berguna — database yang lengkap tapi tanpa file upload yang direferensikannya, atau container yang bisa dijalankan lagi tapi tanpa environment variable yang benar, sama-sama berujung pada aplikasi yang tidak bisa dipulihkan secara utuh.

Untuk stack berbasis Docker, pola yang umum dipakai adalah cron job di host yang menjalankan docker exec ke container database untuk dump terjadwal, lalu menyalin hasilnya (bersama volume file storage) ke lokasi terpisah dari server produksi. Contoh sederhana untuk dump MySQL/MariaDB terjadwal:

0 2 * * * docker exec db-container mysqldump -u user -p'***' appdb | gzip > /backup/appdb-$(date +\%F).sql.gz

Prinsip pentingnya: backup harus berjalan otomatis tanpa campur tangan manual, dan hasilnya harus tersimpan di lokasi yang benar-benar terpisah dari server sumber — baik itu server lain, storage cloud, atau setidaknya disk fisik berbeda. Backup yang tersimpan di server yang sama dengan aplikasinya hanya melindungi dari satu jenis kegagalan (data ter-hapus tidak sengaja), tapi tidak melindungi dari kegagalan yang jauh lebih umum: server itu sendiri mati, disk-nya rusak, atau ada insiden keamanan yang mengenai seluruh mesin.

Retensi: bukan soal menyimpan semuanya selamanya

Backup harian yang menumpuk tanpa batas akan menghabiskan storage sekaligus menyulitkan Anda menemukan titik pulih yang tepat. Pola retensi yang umum dipakai adalah skema bertingkat: simpan backup harian untuk beberapa hari terakhir (misalnya 7 hari), backup mingguan untuk beberapa minggu (misalnya 4 minggu), dan backup bulanan untuk beberapa bulan ke belakang. Skema ini memberi Anda titik pulih yang rapat untuk insiden yang baru terjadi, sekaligus titik pulih yang lebih jarang tapi tetap tersedia untuk masalah yang baru ketahuan belakangan — misalnya korupsi data yang baru terlihat berminggu-minggu setelah kejadian sebenarnya.

Retensi juga perlu disesuaikan dengan regulasi atau kebutuhan bisnis masing-masing. Untuk sistem yang menyimpan data sensitif, sering ada aturan minimal berapa lama data (termasuk backup-nya) harus bisa dipulihkan. Ini bukan keputusan teknis semata, jadi ada baiknya dikonfirmasi ke pihak yang bertanggung jawab atas kepatuhan, bukan diputuskan sepihak oleh yang mengurus infrastruktur.

Yang paling sering dilewatkan: uji restore-nya

Ini bagian yang menurut saya paling penting dan paling sering diabaikan. Banyak tim merasa aman karena "cron job backup-nya jalan tiap malam, log-nya hijau semua" — tapi log yang hijau hanya membuktikan proses dump-nya selesai tanpa error, bukan membuktikan hasilnya benar-benar bisa dipulihkan jadi aplikasi yang hidup lagi. File backup yang korup, dump yang terpotong karena koneksi putus, atau skema yang berubah tanpa backup-nya menyesuaikan, semua itu baru ketahuan saat proses restore benar-benar dicoba — dan sayangnya, momen itu paling sering justru terjadi saat keadaan sedang darurat.

Solusinya adalah menjadikan uji restore sebagai proses terjadwal juga, bukan cuma backup-nya. Secara berkala — misalnya sebulan sekali — ambil salah satu file backup terbaru, dan benar-benar jalankan proses restore-nya ke lingkungan terpisah (bisa staging, bisa environment sekali pakai), lalu verifikasi aplikasinya bisa berjalan dan datanya masuk akal. Latihan ini sekaligus memastikan dokumentasi langkah restore-nya benar-benar akurat dan tidak basi, karena langkah yang cuma ditulis di dokumen tapi tidak pernah dipraktikkan cenderung ketinggalan zaman begitu ada perubahan kecil di infrastruktur.

Ringkasnya

Backup yang baik mencakup database, file storage, dan konfigurasi sekaligus; disimpan otomatis di lokasi yang benar-benar terpisah dari sumbernya; dan mengikuti skema retensi bertingkat yang seimbang antara kerapatan titik pulih dan kebutuhan storage. Tapi semua itu baru punya arti kalau prosesnya benar-benar bisa dipulihkan — dan satu-satunya cara memastikannya adalah dengan menguji restore secara rutin, bukan menganggapnya beres hanya karena backup-nya "jalan".