7.6 KiB
Production Server Checklist BizOne Portal
Panduan ini berisi langkah production 1-7 yang perlu dilakukan di server sebelum aplikasi BizOne Portal dipakai live.
Asumsi deployment:
- Domain:
portal.bizone.id - App path:
/srv/bizone-web - Backend:
127.0.0.1:3001 - Frontend:
127.0.0.1:3000 - PostgreSQL dan Redis memakai Docker Compose dari
deploy/debian12/docker-compose.infra.yml
1. Bersihkan real secret dari repo dan rotate secret
File berikut tidak boleh berisi credential asli:
.env.exampledeploy/debian12/app.env.exampleREADME.md
Isi semua secret di file example cukup memakai placeholder:
DATABASE_URL=postgresql://bizone:change-this-password@127.0.0.1:5432/wa_dashboard
JWT_SECRET=replace-with-32-plus-char-random-secret
JWT_REFRESH_SECRET=replace-with-32-plus-char-random-refresh-secret
WEBHOOK_VERIFY_TOKEN=replace-with-32-plus-char-random-token
WEBHOOK_SHARED_SECRET=replace-with-32-plus-char-random-secret
META_WEBHOOK_APP_SECRET=replace-with-real-meta-app-secret
MAIL_PASSWORD=replace-with-real-smtp-password
Di server, generate secret baru:
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32
Gunakan hasil berbeda untuk:
JWT_SECRETJWT_REFRESH_SECRETWEBHOOK_VERIFY_TOKENWEBHOOK_SHARED_SECRETMETA_WEBHOOK_APP_SECRET
Jika secret lama pernah masuk repo, anggap bocor dan jangan dipakai lagi.
2. Siapkan .env production langsung di server
Masuk server:
ssh user@SERVER_IP
cd /srv/bizone-web
nano .env
Isi minimal seperti ini:
NODE_ENV=production
DATABASE_URL=postgresql://bizone:ISI_PASSWORD_DB_URL_ENCODED@127.0.0.1:5432/wa_dashboard
REDIS_URL=redis://127.0.0.1:6379
PORT=3001
FRONTEND_ORIGIN=https://portal.bizone.id
PUBLIC_API_URL=https://portal.bizone.id
INTERNAL_API_URL=http://127.0.0.1:3001/api
NEXT_PUBLIC_API_URL=https://portal.bizone.id/backend-api
JWT_SECRET=ISI_SECRET_BARU
JWT_EXPIRES_IN=1d
JWT_REFRESH_SECRET=ISI_REFRESH_SECRET_BARU
JWT_REFRESH_EXPIRES_IN=30d
WEBHOOK_VERIFY_TOKEN=ISI_VERIFY_TOKEN_BARU
WEBHOOK_SHARED_SECRET=ISI_SHARED_SECRET_BARU
META_WEBHOOK_APP_SECRET=ISI_META_APP_SECRET_BARU
WEBHOOK_ALLOW_UNSIGNED=false
MAIL_HOST=mail.bizone.id
MAIL_PORT=465
MAIL_SECURE=true
MAIL_USER=no-reply@bizone.id
MAIL_PASSWORD=ISI_PASSWORD_SMTP
MAIL_FROM=BizOne Portal <no-reply@bizone.id>
AUTH_LOGIN_MAX_ATTEMPTS=5
AUTH_LOGIN_WINDOW_MINUTES=15
AUTH_2FA_MAX_ATTEMPTS=5
AUTH_2FA_WINDOW_MINUTES=10
AUTH_PASSWORD_RESET_MAX_ATTEMPTS=3
AUTH_PASSWORD_RESET_WINDOW_MINUTES=30
Amankan permission file .env:
sudo chown bizone:bizone /srv/bizone-web/.env
sudo chmod 600 /srv/bizone-web/.env
Load env untuk command manual:
cd /srv/bizone-web
set -a
source .env
set +a
3. Jalankan build backend dan frontend
Install dependency root untuk Prisma:
cd /srv/bizone-web
npm install
Build backend:
cd /srv/bizone-web/backend
npm install
npm run db:generate
npm run build
Build frontend:
cd /srv/bizone-web/frontend
npm install
npm run build
Jika build gagal, jangan lanjut deploy. Bereskan error terlebih dahulu.
4. Jalankan database migration deploy
Pastikan PostgreSQL dan Redis hidup:
cd /srv/bizone-web/deploy/debian12
docker compose -f docker-compose.infra.yml up -d
docker compose -f docker-compose.infra.yml ps
Jalankan migration:
cd /srv/bizone-web
set -a
source .env
set +a
cd backend
npm run db:migrate:deploy
Jika database masih kosong dan butuh admin awal:
npm run seed:admin
Setelah login pertama, langsung ganti password admin dan aktifkan 2FA.
5. Tambahkan nginx security headers
Edit config nginx:
sudo nano /etc/nginx/sites-available/portal.bizone.id
Di dalam blok server { ... }, tambahkan:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Pastikan route penting tetap seperti ini:
location = /api/health {
proxy_pass http://127.0.0.1:3001/api/health;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/webhooks/ {
proxy_pass http://127.0.0.1:3001/api/webhooks/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /backend-api/ {
proxy_pass http://127.0.0.1:3001/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Test dan reload nginx:
sudo nginx -t
sudo systemctl reload nginx
6. Deploy via systemd
Copy service files:
sudo cp /srv/bizone-web/deploy/debian12/bizone-backend.service /etc/systemd/system/
sudo cp /srv/bizone-web/deploy/debian12/bizone-frontend.service /etc/systemd/system/
Reload systemd:
sudo systemctl daemon-reload
Enable service:
sudo systemctl enable bizone-backend
sudo systemctl enable bizone-frontend
Start atau restart service:
sudo systemctl restart bizone-backend
sudo systemctl restart bizone-frontend
Cek status:
sudo systemctl status bizone-backend
sudo systemctl status bizone-frontend
Lihat log kalau ada error:
sudo journalctl -u bizone-backend -f
sudo journalctl -u bizone-frontend -f
7. Smoke test production
Cek backend health:
curl https://portal.bizone.id/api/health
curl https://portal.bizone.id/backend-api/health
Response ideal:
{"status":"ok","service":"wa-dashboard-backend","database":"ok"}
Cek frontend:
curl -I https://portal.bizone.id
Cek service:
sudo systemctl is-active bizone-backend
sudo systemctl is-active bizone-frontend
docker compose -f /srv/bizone-web/deploy/debian12/docker-compose.infra.yml ps
Test manual dari browser:
- Buka
https://portal.bizone.id. - Login admin.
- Ganti password admin default.
- Aktifkan 2FA.
- Buka dashboard.
- Buka
Settings > WhatsApp API Setting. - Pastikan secret tidak tampil sebagai plain text di production.
- Buka
Webhook Logs. - Test webhook verification dari Meta.
- Kirim pesan WhatsApp ke nomor bisnis.
- Pastikan pesan masuk di Conversations.
- Balas dari dashboard jika token Meta dan phone number ID sudah benar.
Meta callback production:
https://portal.bizone.id/api/webhooks/whatsapp
Verify token:
Pakai nilai WEBHOOK_VERIFY_TOKEN dari .env production.
Catatan setelah smoke test
Jika semua smoke test lolos, lanjutkan dengan hardening tambahan:
- Setup backup PostgreSQL terjadwal.
- Setup monitor uptime ke
/api/health. - Setup log retention
journald. - Audit dependency dengan
npm auditdi root, backend, dan frontend. - Rotate admin password dan wajibkan 2FA untuk akun admin.