D
Dehuyz Gateway
Docs VPS Migration

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/*.dump lama (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.