Skip to content

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 deployment

Karakteristik Utama: ​

  1. Zero-Downtime & Atomic Symlink Switch: Switch versi dilakukan dengan ln -sfn releases/<n> current, sehingga perpindahan versi terjadi dalam satu operasi sistem berkas atomik.
  2. Shared State Isolation: .env, storage direktori, dan berkas database.sqlite berada di direktori shared/ dan di-symlink ke setiap release aktif. Rerun atau upgrade tidak menimpa data pengguna.
  3. Dedicated User & Permissions: Seluruh release dan shared file dimiliki oleh user sistem dracin:dracin dengan mode direktori 755/751 dan berkas 640. Pool PHP-FPM berjalan sebagai dracin, 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/dist

Isi 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 (default 22 atau port kustom mis. 20700).
  • --user USER: User SSH target (default root).
  • --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 (default staging.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 \
  --apply

4. 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 selesai

5. 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 640 milik dracin:dracin.
  • Retensi: menyimpan 5 backup snapshot terakhir secara otomatis.

Mitigasi Kegagalan Migrasi ​

Jika perintah artisan:migrate mengembalikan error:

  1. Deployer menangkap eksepsi kegagalan.
  2. Snapshot backup yang baru saja dibuat segera di-restore ke /var/www/dracin/shared/database/database.sqlite.
  3. Deployment dibatalkan dan symlink current tidak 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 \
  --apply

7. Health Check Otomatis & Rollback Kode ​

Verifikasi Health Check ​

Setelah symlink current dialihkan ke rilis baru dan PHP-FPM di-reload, Deployer menjalankan probe otomatis:

  1. Memeriksa status proses php8.4-fpm.
  2. Melakukan HTTP GET request ke Nginx melalui loopback http://127.0.0.1/ dengan header Host: <domain> dan User-Agent yang sah.
  3. Memeriksa status code HTTP 200, 301, atau 302.
  4. Memeriksa endpoint kesehatan bawaan Laravel /up.

Automatic Rollback on Failure ​

Jika health check mendeteksi kegagalan (misal respons 500/404 atau server crash):

  1. Task deploy:failed dipicu secara otomatis.
  2. Deployer menjalankan rollback, mengalihkan kembali symlink current ke rilis sebelumnya.
  3. Service php8.4-fpm di-reload.
  4. Health check rilis sebelumnya diverifikasi ulang untuk memastikan server kembali stabil.
  5. 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 \
  --apply

8. Verifikasi Lokal Cepat ​

Untuk memvalidasi sintaks dan logika deployment secara lokal dalam lingkungan terisolasi:

bash
scripts/test-deploy-release.sh

Pengujian 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 SSHPASS pada sesi pengujian terotorisasi. Berkas .env.deploy dilindungi oleh .gitignore.
  • Ownership & Permissions: File konfigurasi .env dan database database.sqlite diatur ke mode 640 milik dracin:dracin, tidak dapat diakses secara publik oleh web browser maupun user sistem biasa.

AGC Dracin — Platform streaming drama mandiri berkinerja tinggi untuk komunitas Dojo.