# Backup, upgrade, pemulihan dan diagnosis Semua perintah dijalankan dari direktori release yang benar dengan path env privat absolut. Simpan versi source, image tag/ID, hash arsip, konfigurasi, waktu migrasi, hasil smoke dan nama backup dalam receipt privat. Jangan simpan secrets dalam repository atau screenshot/log publik. ## Backup dan restore ```sh sh deploy/staging.sh /private/bereaware-staging/staging.env backup sh deploy/staging.sh /private/bereaware-staging/staging.env restore-check /private/bereaware-staging/backups/bereaware-TIMESTAMP.dump ``` Backup adalah custom-format `pg_dump` konsisten; script memverifikasi daftar arsip, menulis SHA-256 dan menolak file kosong. Media saat ini disimpan bersama database; jika nanti storage eksternal ditambahkan, snapshot storage dan manifest referensi juga wajib dibackup. Salin dump dan env secara terenkripsi ke tempat di luar VM. Jadwalkan backup melalui scheduler operator yang memanggil perintah di atas, periksa exit code, dan tentukan retensi serta penghapusan secara eksplisit. Script tidak menghapus backup lama. Restore-check hanya membuat database baru `bereaware_restore__`, menjalankan restore transaksi tunggal dan menghitung organisasi/jemaat/publikasi. Database sumber tidak disentuh. Database pemeriksaan ditahan untuk inspeksi; hapus hanya nama yang tercetak setelah diterima. Keberhasilan `pg_restore --list` saja bukan bukti pemulihan. Catat jumlah data dan uji login/publikasi pada environment disposable sebelum menerima backup sebagai layak. ## Upgrade dan rollback Gunakan tag unik dalam `RELEASE_TAG`, bukan menimpa image rilis terakhir. Persiapkan release baru dari source tervalidasi dengan project/env yang sama dan jadwal maintenance yang sesuai. Jalankan: ```sh sh deploy/staging.sh /private/bereaware-staging/staging.env upgrade node deploy/smoke.mjs /private/bereaware-staging/staging.env ``` Script memvalidasi, membangun image serial, mencatat image sebelumnya, mengambil backup, lalu menjalankan migrasi dan `up --wait`. Build gagal tidak menyentuh container aktif. Compose bukan deployment atomik: sebagian container dapat berpindah sebelum layanan lain gagal. Jangan menyebut rollback otomatis atau zero downtime. Pertahankan source/image lama, backup database, env lama dan konfigurasi Caddy terakhir. Tidak ada prune/down/restore otomatis. Bila gagal, simpan `docker compose --env-file ... -f compose.staging.yaml ps` dan `logs --tail 100`, tinjau perubahan skema, dan tentukan apakah image sebelumnya kompatibel. Restore skema/data lama hanya pada database/volume pengganti yang telah diuji, dengan maintenance dan keputusan operator; jangan menimpa volume sumber atau mengulang migrasi tak pasti. Caddy tidak perlu diubah untuk upgrade image pada port yang sama. Bila harus mengubah proxy, bandingkan hash sumber dengan receipt, buat backup eksak, validasi config kandidat lalu reload. Pada kegagalan validasi/reload, pertahankan config aktif dan periksa status sebelum mencoba lagi. Periksa layanan tetangga sebelum/sesudah deployment. ## Pemantauan dan troubleshooting - Status: `sh deploy/staging.sh /private/bereaware-staging/staging.env status` dan smoke per host. Health container tidak membuktikan DNS/HTTPS, otorisasi atau journey pengguna. - Monitor eksternal HTTPS untuk enam host, masa sertifikat, HTTP 5xx, disk/volume/backup age, OOM/restart dan pool/latensi database. Log container dibatasi 3 × 10 MiB per service; jangan log cookie, secret atau data jemaat. - 421: Host tidak sesuai origin. 403 gateway: header hop dari Caddy hilang atau Origin salah. Jangan memperbaiki dengan membuka wildcard origin atau mempercayai XFF. - 503: periksa health API, migrasi dan koneksi DB. Unknown church/path harus gagal; jangan mengganti scope secara diam-diam. - Asset Flutter 404: verifikasi build web ikut image; gateway tidak memberi index.html untuk asset hilang atau typo API. Deep link member tanpa ekstensi memakai SPA fallback. - Port bentrok: ubah keenam port env secara konsisten, regenerasi fragmen Caddy yang ditinjau dan validasi. Port tetap loopback. - Banyak pengguna Wi-Fi: Caddy mengirim IP koneksi yang sama untuk pengguna NAT; rate limit backend tetap harus sesuai journey. Gateway mencegah seluruh pengguna tereduksi menjadi satu IP container; NAT publik tetap tidak dapat dibedakan sebagai IP unik. Tidak ada uji restore/deployment yang boleh diklaim hanya dari validasi file atau unit test. Jalankan dan simpan bukti runtime pada instalasi terisolasi. ## Jadwal backup opsional Template `deploy/bereaware-backup.service` dan `.timer` tersedia untuk ditinjau operator. Service membaca `/etc/bereaware-staging/backup-paths.env` berisi hanya dua path absolut `BEREAWARE_RELEASE` dan `BEREAWARE_ENV`. Operator menginstal unit setelah mencoba backup manual, memeriksa isi path dan akses Docker, lalu mengaktifkan timer. Jadwal default 19:00 UTC (02:00 WIB) dengan jitter 10 menit dan catch-up saat host kembali hidup. Panggilan systemd gagal terlihat pada exit code/journal; hubungkan alert yang dimiliki operator. Tidak ada unit diaktifkan otomatis oleh source package. Rotasi/retensi backup harus ditentukan terpisah setelah salinan off-host dan restore diperiksa. ## Batas bukti restore-check Helper saat ini memakai `--no-owner --no-privileges` untuk restore pemeriksaan. Ia memverifikasi struktur/data dan jumlah organisasi/jemaat/publikasi melalui akun postgres di database baru, bukan hak akses runtime `mychurch_app`. Untuk menerima pemulihan aplikasi, operator juga perlu memulihkan ACL asli hanya pada database disposable yang sama dan menguji koneksi/journey aplikasi di environment terisolasi. Jangan mengubah password atau role cluster bersama untuk pemeriksaan ini. Dump PostgreSQL tidak mencakup role global; backup konfigurasi/secrets dikelola terpisah secara privat. Pilih dump tepat dari hasil perintah backup, bukan file 'terbaru' yang belum direkonsiliasi. `pg_restore --list` dan pemeriksaan data bukan uji login atau media dari browser. Bila backup/restore terinterupsi, pertahankan `.tmp`, manifest dan nama database pemeriksaan sebagai bukti; jangan otomatis mengulang operasi atau menjatuhkan database sumber.