Appearance
Panduan Deployment Release PHP Deployer di VPS
Dokumentasi ini menjelaskan konfigurasi, packaging, deployment atomik, health check, rollback, dan mitigasi pemulihan database untuk aplikasi Dracin pada VPS Ubuntu 24.04 menggunakan PHP Deployer.
Pengguna nantinya akan menjalankan operasi ini secara otomatis melalui launcher wizard lokal. Panduan ini adalah referensi operasional dan arsitektur resmi (Single Source of Truth).
1. Arsitektur Deployment Atomik
Dracin menggunakan standar PHP Deployer v7 dengan struktur direktori atomik di VPS target (default /var/www/dracin):
/var/www/dracin/
├── current -> releases/<n> # Symlink atomik ke release aktif
├── releases/ # Koleksi direktori release berversi
│ ├── 1/ # Release 1
│ ├── 2/ # Release 2
│ └── 3/ # Release 3
├── shared/ # State persisten lintas release
│ ├── .env # Konfigurasi environment (APP_KEY, domain, dll.)
│ ├── database/
│ │ ├── database.sqlite # Database SQLite utama
│ │ └── backups/ # Snapshot backup pre-migration
│ │ ├── database_1_*.sqlite
│ │ └── database_2_*.sqlite
│ └── storage/ # Storage upload, cache, sessions, views, logs
│ ├── app/public/
│ ├── framework/cache/
│ ├── framework/sessions/
│ ├── framework/views/
│ └── logs/
└── .dep/
└── deploy.lock # Lockfile pencegah concurrent deploymentKarakteristik Utama:
- Zero-Downtime & Atomic Symlink Switch: Switch versi dilakukan dengan
ln -sfn releases/<n> current, sehingga perpindahan versi terjadi dalam satu operasi sistem berkas atomik. - Shared State Isolation:
.env, storage direktori, dan berkasdatabase.sqliteberada di direktorishared/dan di-symlink ke setiap release aktif. Rerun atau upgrade tidak menimpa data pengguna. - Dedicated User & Permissions: Seluruh release dan shared file dimiliki oleh user sistem
dracin:dracindengan mode direktori 755/751 dan berkas 640. Pool PHP-FPM berjalan sebagaidracin, sedangkan Nginx (www-data) memiliki akses traversal dan socket FastCGI.
2. Packaging Release Artefak (scripts/package-release.sh)
Untuk mendistribusikan Dracin kepada pembeli tanpa memerlukan akses kredensial ke repositori privat GitHub, release dibundel ke dalam tarball mandiri (.tar.gz) yang disertai berkas checksum SHA-256 (.sha256).
Cara Membuat Paket Release:
bash
# Build release paket v1.0.0 (output default di releases/)
scripts/package-release.sh --version v1.0.0
# Opsi kustom direktori output
scripts/package-release.sh --version v1.0.0 --out-dir /path/to/distIsi Paket:
- Source code produksi:
app/,bootstrap/,config/,database/,public/(termasuk manifest & bundle frontend Vite),resources/,routes/. - Dependensi PHP produksi:
vendor/(siap saji, tanpa require dev). - Metadata versi: berkas
VERSION. - Dikecualikan dari paket:
.git, berkas.env*,tests/,node_modules/,storage/aktif, utility development.
3. Eksekusi Deployment (scripts/deploy-release.sh)
Script scripts/deploy-release.sh mengorkestrasi pipeline deployment atomik baik secara remote via SSH maupun langsung di VPS (--local).
Opsi CLI:
--host HOST: Hostname atau IP target VPS (mis.167.86.108.118).--port PORT: Port SSH target (default22atau port kustom mis.20700).--user USER: User SSH target (defaultroot).--app-dir PATH: Path instalasi di server (default/var/www/dracin).--artifact PATH_OR_URL: Path file tarball lokal atau URL HTTP/HTTPS unduhan artefak.--version VERSION: Label versi (mis.v1.0.0).--checksum SHA256: Checksum SHA-256 opsional untuk memvalidasi integritas sebelum ekstraksi.--domain DOMAIN: Domain target untuk health check HTTP (defaultstaging.dracin.test).--rollback: Melakukan rollback atomik ke release sebelumnya.--restore-db BACKUP_PATH: Memulihkan database SQLite dari berkas snapshot backup.--dry-run: Validasi argumen dan tampilkan rencana tanpa mutasi.--apply: Eksekusi operasi deployment nyata.
Contoh Penggunaan:
bash
# 1. Dry run (verifikasi parameter tanpa koneksi/perubahan)
scripts/deploy-release.sh \
--host 167.86.108.118 \
--port 20700 \
--user root \
--artifact releases/dracin-v1.0.0.tar.gz \
--version v1.0.0 \
--domain staging.dracin.test \
--dry-run
# 2. Deploy Release Awal (v1)
scripts/deploy-release.sh \
--host 167.86.108.118 \
--port 20700 \
--user root \
--artifact releases/dracin-v1.0.0.tar.gz \
--version v1.0.0 \
--domain staging.dracin.test \
--apply
# 3. Deploy Update Release Berbasis URL (Remote Download)
scripts/deploy-release.sh \
--host 167.86.108.118 \
--port 20700 \
--user root \
--artifact https://downloads.example.com/dracin/dracin-v2.0.0.tar.gz \
--version v2.0.0 \
--checksum 8afaaf873689089b896f9822da888f779efbc462378d3e7e9acc3c48ae2ef255 \
--domain staging.dracin.test \
--apply4. Pipeline Deployer Tasks
Saat dijalankan, recipe deploy.php mengeksekusi urutan task berurutan:
deploy
├── deploy:prepare
│ ├── deploy:info # Logging informasi target dan rilis
│ ├── deploy:setup # Verifikasi direktori target
│ ├── deploy:lock # Pasang lockfile (.dep/deploy.lock)
│ ├── deploy:release # Buat direktori releases/<n>
│ ├── deploy:update_code # Unduh/ekstrak artefak & verifikasi checksum
│ ├── deploy:env # Persiapkan symlink .env
│ ├── deploy:shared # Symlink direktori shared (storage)
│ ├── deploy:shared:sqlite # Symlink database/database.sqlite -> shared
│ └── deploy:writable # Set permission storage dan cache
├── database:backup # Backup SQLite otomatis ke shared/database/backups/
├── artisan:storage:link # Buat symlink public/storage -> storage/app/public
├── artisan:config:cache # Cache konfigurasi Laravel
├── artisan:route:cache # Cache routing
├── artisan:view:cache # Kompilasi blade view cache
├── artisan:migrate # Eksekusi database migrations (auto-restore on failure)
├── deploy:symlink # Atomik switch: current -> releases/<n>
├── php-fpm:reload # Reload php8.4-fpm untuk refresh worker dan OPcache
├── deploy:health_check # Probe HTTP live (200 OK) pada domain dan endpoint /up
├── deploy:unlock # Lepas lockfile deployment
├── deploy:cleanup # Hapus release lama (retensi 5 rilis terakhir)
└── deploy:success # Konfirmasi deployment selesai5. Deployment Lock & Proteksi Bersamaan
Deployer secara otomatis memasang lock pada awal pipeline (deploy:lock) dan membukanya di akhir (deploy:unlock). Jika proses deployment lain sedang berjalan, deployment baru akan ditolak dengan aman untuk mencegah tabrakan data dan symlink race conditions.
Jika proses terhenti secara paksa di tengah jalan:
bash
# Buka lock secara manual pada target
ssh -p PORT USER@HOST 'dep deploy:unlock -f /var/www/dracin/deploy.php'6. Backup Database & Pemulihan (Disaster Recovery)
Pre-Migration Backup Otomatis
Sebelum setiap task artisan:migrate berjalan, Deployer secara otomatis membuat snapshot backup SQLite menggunakan SQLite Online Backup API (sqlite3 .backup atau cp atomik):
- Lokasi:
/var/www/dracin/shared/database/backups/database_<release>_<timestamp>.sqlite - Permission: mode
640milikdracin:dracin. - Retensi: menyimpan 5 backup snapshot terakhir secara otomatis.
Mitigasi Kegagalan Migrasi
Jika perintah artisan:migrate mengembalikan error:
- Deployer menangkap eksepsi kegagalan.
- Snapshot backup yang baru saja dibuat segera di-restore ke
/var/www/dracin/shared/database/database.sqlite. - Deployment dibatalkan dan symlink
currenttidak diubah.
Pemisahan Rollback Kode vs Rollback Database
Rollback kode aplikasi tidak secara otomatis me-rollback database. Hal ini dirancang untuk mencegah hilangnya data transaksi pengguna yang valid setelah rilis baru aktif.
Jika operator memutuskan untuk memulihkan skema/data database ke snapshot tertentu:
bash
scripts/deploy-release.sh \
--host 167.86.108.118 \
--port 20700 \
--user root \
--restore-db /var/www/dracin/shared/database/backups/database_2_20261015_164204.sqlite \
--apply7. Health Check Otomatis & Rollback Kode
Verifikasi Health Check
Setelah symlink current dialihkan ke rilis baru dan PHP-FPM di-reload, Deployer menjalankan probe otomatis:
- Memeriksa status proses
php8.4-fpm. - Melakukan HTTP GET request ke Nginx melalui loopback
http://127.0.0.1/dengan headerHost: <domain>dan User-Agent yang sah. - Memeriksa status code HTTP
200,301, atau302. - Memeriksa endpoint kesehatan bawaan Laravel
/up.
Automatic Rollback on Failure
Jika health check mendeteksi kegagalan (misal respons 500/404 atau server crash):
- Task
deploy:faileddipicu secara otomatis. - Deployer menjalankan
rollback, mengalihkan kembali symlinkcurrentke rilis sebelumnya. - Service
php8.4-fpmdi-reload. - Health check rilis sebelumnya diverifikasi ulang untuk memastikan server kembali stabil.
- Lockfile dilepas dan status error dilaporkan secara transparan.
Manual Rollback
Operator atau wizard dapat menjalankan rollback kapan saja:
bash
scripts/deploy-release.sh \
--host 167.86.108.118 \
--port 20700 \
--user root \
--domain staging.dracin.test \
--rollback \
--apply8. Verifikasi Lokal Cepat
Untuk memvalidasi sintaks dan logika deployment secara lokal dalam lingkungan terisolasi:
bash
scripts/test-deploy-release.shPengujian ini mencakup:
- Verifikasi packaging dan integritas SHA-256.
- Validasi pohon tugas Deployer (
deploy.php). - Pengujian backup dan restore database SQLite.
- Validasi penolakan artefak dengan checksum corrupt.
- Verifikasi mode
--dry-run. - Waktu eksekusi targeted: < 5 detik.
9. Keamanan & Penanganan Kredensial
- Tanpa Hardcoded Secrets: Tidak ada IP, token, password SSH, atau APP_KEY yang disimpan di dalam Git atau repositori publik.
- Kredensial SSH: Menggunakan native OpenSSH prompts atau environment variable
SSHPASSpada sesi pengujian terotorisasi. Berkas.env.deploydilindungi oleh.gitignore. - Ownership & Permissions: File konfigurasi
.envdan databasedatabase.sqlitediatur ke mode640milikdracin:dracin, tidak dapat diakses secara publik oleh web browser maupun user sistem biasa.