Lewati ke konten utama

Deployment

Tiga lingkungan, tiga cara kerja berbeda.


Peta lingkungan

Produksi dan staging bukan cermin

Produksi memakai PostgreSQL + Docker; staging memakai MySQL + bare metal. Migrasi ber-SQL mentah bisa lolos di satu dan gagal di yang lain. Staging berjalan lebih dulu, jadi ia adalah peringatan dini — terutama untuk migrasi baru.


Alur deploy standar


Klasifikasi perubahan

Apa yang berubah menentukan apa yang dikerjakan skrip deploy:

Yang berubahEfek pada deploy
composer.json / composer.lockMenjalankan composer install --no-dev
resources/, package*.json, vite.config.jsMenjalankan npm ci && npm run build
Migrasi barumigrate --force selalu berjalan — tapi migrasi baru wajib diuji di staging dulu
app/, routes/, config/, bootstrap/Cache dibangun ulang (selalu)
.env*⚠️ Diterapkan manual per server — jangan pernah commit rahasia
docker/, docker-compose.yml, skrip deploy⚠️ Skrip tidak menerapkannya — perlu tindakan manual

Direktori public/ selalu "kotor"

public/ permanen kotor di kedua server karena Filament menerbitkan ulang aset vendornya setiap deploy. Kedua skrip sinkronisasi menjalankan git checkout -- public/ sebelum merge, dan menyimpan (stash) sisanya. public/build masuk gitignore sehingga output Vite dibangun ulang per server.

Jangan "perbaiki" pohon kerja kotor di server

Ini perilaku yang diharapkan, bukan masalah.


Staging — otomatis

ItemNilai
URLhttps://crmrsi-staging.balascepat.com
Path/var/www/crmrsi-staging
RuntimeApache 2.4 + PHP 8.3-FPM, MySQL
Skrip sinkronisasi/usr/local/bin/crmrsi-staging-sync.sh
Kadenscron */5 * * * *
Log/home/cakmat/logs/crmrsi-staging-sync.log
Berkas status/home/cakmat/logs/crmrsi-staging-sync.status
Layanansystemd crmrsi-staging-queue, crmrsi-staging-scheduler

Berkas status berisi satu baris: OK <sha> at <YYYY-MM-DD HH:MM:SS>. Cocokkan sha-nya dengan git rev-parse --short HEAD lokal.

Kalau staging gagal, JANGAN deploy ke produksi

Baris status bukan OK, atau log berisi error migrasi → perbaiki dan push ulang.

Catatan staging:

  • Node dipasang manual di /usr/local/lib/nodejs. Jangan pakai apt/NodeSource — sumber apt-nya rusak dan hanya menawarkan Node 12.
  • Job sinkronisasi punya NOPASSWD sudo untuk tepat tiga panggilan systemctl. Jangan diperluas.
  • Setiap sinkronisasi nyata membuat mysqldump ke /home/cakmat/backups/db (~227 MB, disimpan 14 terakhir).

Produksi — manual, disengaja

ItemNilai
URLhttps://crmrsi.balascepat.com
Server103.59.161.170
Direktori stack/var/www/crm-hospital
Direktori aplikasi/var/www/crm-hospital/src
Skrip deploy/usr/local/bin/crm-hospital-deploy.sh
Log deploy/var/log/crm-hospital-deploy.log
Cadangan DB/var/www/crm-hospital/backups/db (gzip, 14 terakhir)

Cek dulu, deploy kemudian

/usr/local/bin/crm-hospital-deploy.sh --check

Mencetak up to date at <sha> atau behind by N commit(s): <a> -> <b>tidak menyentuh apa pun.

/usr/local/bin/crm-hospital-deploy.sh

Yang dikerjakan skrip

Semua perintah PHP berjalan lewat docker exec crm_php.

Flag --force memaksa langkah composer + npm walaupun tidak ada perubahan — berguna untuk membangun ulang aset saat sha sudah sama.

Deploy panjang

Deploy yang menyentuh npm ci butuh lebih dari 2 menit. Jalankan di latar dan pantau /var/log/crm-hospital-deploy.log.

Kalau deploy gagal

Skrip berhenti dengan pesan jelas dan mencetak petunjuk pemulihan untuk migrasi yang bermasalah:

gunzip < /var/www/crm-hospital/backups/db/laravel_db-<ts>.sql.gz \
| docker exec -i crm_postgres psql -U laravel_user -d laravel_db

Perubahan lokal yang di-stash bisa dipulihkan dengan git stash list di dalam /var/www/crm-hospital/src.


Smoke test setelah deploy

curl -sI https://crmrsi.balascepat.com | head -1
curl -s -o /dev/null -w "admin/login %{http_code}\n" https://crmrsi.balascepat.com/admin/login

Kesehatan kontainer:

docker ps --format "{{.Names}}\t{{.Status}}" | grep crm_
docker logs --tail 20 crm_queue
docker exec crm_php php artisan about --only=environment | head -20
docker exec crm_php php artisan schedule:list

Harapan: semua kontainer crm_* Up, crm_queue dan crm_scheduler baru saja di-restart, /admin/login mengembalikan 200.

Lalu buka halaman yang benar-benar tersentuh perubahan (mis. /admin/chat-rooms untuk pekerjaan chat).


Rollback

Hanya kode

# Lokal — staging mengambilnya dalam 5 menit
git revert <sha>
git push origin main

# Produksi
/usr/local/bin/crm-hospital-deploy.sh

Migrasi yang harus dibatalkan

KondisiTindakan
Migrasi punya down() yang berfungsidocker exec crm_php php artisan migrate:rollback --step=N --force
Tidak punya down()Pulihkan dari cadangan gzip pra-deploy, atau tulis migrasi perbaikan
Jangan pernah
  • migrate:fresh atau db:wipe di server mana pun
  • Mengedit manual berkas migrasi yang sudah berjalan di server
  • git push --force ke main tanpa persetujuan eksplisit
  • Menyalin database antar server — hanya skema yang berpindah, lewat migrate --force

Deploy dokumentasi ini

Situs Docusaurus dibangun di lokal, hasilnya berupa berkas statis yang disalin ke server.

Kenapa dibangun di lokal

Disk root server produksi hampir penuh. node_modules Docusaurus berukuran ratusan megabita, sedangkan hasil build statisnya hanya belasan megabita.

Vhost nginx dan sertifikat Let's Encrypt disiapkan sekali; pembaruan berikutnya cukup npm run build + rsync.


Anti-pola

❌ Jangan✅ Lakukan
Deploy ke produksi sebelum staging hijauCocokkan sha di berkas status staging dulu
Menganggap produksi dan staging samaPostgreSQL vs MySQL, Docker vs bare metal
git pull atau edit kode langsung di serverRepo lokal adalah sumber kebenaran; server hanya fast-forward
docker exec crm_php php artisan migrate manualPakai skrip deploy — ia mencadangkan DB dulu
Commit .env atau rahasiaTerapkan manual per server setelah konfirmasi
Menyentuh kontainer wahaLayanan tak terkait di server yang sama
Menjalankan deploy npm ci di foregroundJalankan di latar + pantau log