VPS Migration
Pindah VPS bisa karena: provider rebuild, upgrade resource, ganti region, atau beli VPS baru yang lebih murah. Dehuyz Gateway dirancang untuk portable — semua state ada di Postgres + filesystem /opt/qris-gateway/.
TL;DR
./scripts/migrate-vps.sh \ --old-host 167.71.196.205 \ --new-host <NEW-IP> \ --ssh-key ~/.ssh/do_sgp2
Total ~5-10 menit dari laptop. Downtime ~2-3 menit (selama pg_restore jalan).
Apa yang dipindah
Script meng-handle 6 layer:
| # | Item | Source | Target |
|---|---|---|---|
| 1 | Code repo | GitHub (deploy key) | git clone |
| 2 | Database | pg_dump di old VPS |
pg_restore di new VPS |
| 3 | Secrets | .env.local (chmod 600) |
scp transfer |
| 4 | BRI session | session.json, session.device |
scp transfer (opsional) |
| 5 | systemd unit | /etc/systemd/system/qris-gateway.service |
copy as-is |
| 6 | Caddy config | /etc/caddy/Caddyfile |
copy as-is |
Persyaratan VPS baru
- Ubuntu 24.04 LTS (atau Debian 12)
- Min 2GB RAM, 20GB disk
- Akses root via SSH key (key sama dengan VPS lama, atau key baru)
- Port 22, 80, 443 reachable
Script auto-install: Python 3.12, Postgres 16, Caddy v2, git.
Langkah manual (kalau script gagal)
1. Backup di VPS lama
ssh root@OLD-IP "/usr/local/bin/qris-backup.sh" scp root@OLD-IP:/var/backups/postgres/qris_gateway_prod_*.dump ./backup.dump scp root@OLD-IP:/opt/qris-gateway/.env.local ./ scp root@OLD-IP:/opt/qris-gateway/session.* ./ scp root@OLD-IP:/etc/systemd/system/qris-gateway.service ./ scp root@OLD-IP:/etc/caddy/Caddyfile ./
2. Stop service di VPS lama
ssh root@OLD-IP "systemctl stop qris-gateway"
⚠️ Critical: gak boleh dua VPS jalan bareng — BRI portal cuma allow 1 device login. Kalau bareng, dua-duanya keluar-masuk.
3. Setup VPS baru
ssh root@NEW-IP <<'EOF' apt-get update apt-get install -y python3-pip python3-venv postgresql-16 postgresql-contrib-16 caddy git # Postgres (ganti PASSWORD sesuai .env.local) sudo -u postgres psql -c "CREATE USER qris_prod WITH PASSWORD 'PASSWORD';" sudo -u postgres psql -c "CREATE DATABASE qris_gateway_prod OWNER qris_prod;" sudo -u postgres psql -d qris_gateway_prod -c "CREATE EXTENSION pgcrypto;" # Deploy key ssh-keygen -t ed25519 -f /root/.ssh/github_deploy -N '' cat /root/.ssh/github_deploy.pub EOF
Paste public key ke https://github.com/Dehuyz1/qris-gateway/settings/keys.
4. Restore di VPS baru
scp ./backup.dump root@NEW-IP:/tmp/ ssh root@NEW-IP <<'EOF' sudo -u postgres pg_restore --no-owner --role=qris_prod -d qris_gateway_prod -c /tmp/backup.dump git clone git@github.com:Dehuyz1/qris-gateway.git /opt/qris-gateway cd /opt/qris-gateway python3 -m venv .venv .venv/bin/pip install -r requirements.txt EOF scp ./.env.local root@NEW-IP:/opt/qris-gateway/.env.local ssh root@NEW-IP "chmod 600 /opt/qris-gateway/.env.local" scp ./session.* root@NEW-IP:/opt/qris-gateway/ scp ./qris-gateway.service root@NEW-IP:/etc/systemd/system/ scp ./Caddyfile root@NEW-IP:/etc/caddy/Caddyfile
5. Start service
ssh root@NEW-IP <<'EOF' systemctl daemon-reload systemctl enable --now qris-gateway systemctl restart caddy ufw allow 22,80,443/tcp ufw enable # Verify systemctl is-active qris-gateway curl http://localhost:2342/api/v1/health EOF
6. Switch DNS / IP
| Setup | Action |
|---|---|
| Pakai domain | Update A record di DNS provider → IP baru. Tunggu propagate (5-30 menit). Cek dig your-domain.com. |
| IP-only (no domain) | Update kode customer integrator — semua tempat yang hardcode IP lama. |
7. Decommission VPS lama
Tunggu 24-48 jam observasi VPS baru. Pastikan:
- Tidak ada error di
journalctl -u qris-gateway - Pembayaran masuk normal
- Customer integrator gak komplain
Setelah aman, destroy VPS lama via DO panel.
Hal yang gak harus di-pindah
pg_backup.log(will recreate)logs/app.log(rotated, akan terbentuk lagi).venv/(di-recreate via pip install)/var/backups/postgres/*.dumplama (overwrite oleh dump baru)
Edge cases
"BRI session jadi invalid setelah pindah"
Normal kalau dua VPS sempet jalan bareng. Solusi:
ssh root@NEW-IP "systemctl restart qris-gateway" # auto re-login BRI di startup
Atau lewat /admin/bri-status → klik Force reconnect.
"Postgres password tidak match"
Cek .env.local di VPS baru — DATABASE_URL=postgresql+asyncpg://qris_prod:PASSWORD@.... Pastikan PASSWORD di sini = password yang dipakai saat CREATE USER qris_prod.
"Customer pakai IP hardcode, gak ada domain"
Update di kode mereka. Atau setup nginx/caddy reverse proxy di IP lama buat redirect ke IP baru selama transitional period.
High Availability (skip migrasi)
Kalau lo mau gak perlu pindah-pindah lagi: setup 2 VPS dengan load balancer. Effort 1-2 hari, tapi sekali setup, reboot/migrate nanti tinggal target 1 VPS aja, 1 VPS lagi tetap serve traffic. Lihat panduan terpisah (Phase 7+, belum dibuat).
Backup tanpa pindah VPS
Untuk routine backup lokal lo (download dump ke laptop):
ssh root@OLD-IP "/usr/local/bin/qris-backup.sh" scp root@OLD-IP:/var/backups/postgres/qris_gateway_prod_$(date +%F)_*.dump ./
Otomatisasi via GitHub Actions / cron lokal kalau lo perlu off-VPS backup.