Files
BizOne-portal/deploy/debian12

Deploy Debian 12 for portal.bizone.id

Panduan ini menyiapkan bizone-web di server Debian 12 kosong dengan topologi berikut:

  • nginx sebagai reverse proxy publik
  • frontend Next.js pada 127.0.0.1:3000
  • backend NestJS pada 127.0.0.1:3001
  • PostgreSQL dan Redis via Docker Compose
  • TLS dari Let's Encrypt

URL Production Final

  • Aplikasi: https://portal.bizone.id
  • Backend API browser/server base URL via reverse proxy: https://portal.bizone.id/backend-api
  • Health check backend: https://portal.bizone.id/api/health
  • Webhook verify URL Meta: https://portal.bizone.id/api/webhooks/whatsapp
  • Webhook event URL Meta: https://portal.bizone.id/api/webhooks/whatsapp
  • Alternate provider-specific webhook URL: https://portal.bizone.id/api/webhooks/whatsapp/meta
  • Webhook logs UI: https://portal.bizone.id/dashboard/webhooks/logs

Untuk integrasi Meta, gunakan URL default berikut:

  • Callback URL: https://portal.bizone.id/api/webhooks/whatsapp
  • Verify token: nilai WEBHOOK_VERIFY_TOKEN yang sama persis dengan env production

Catatan penting:

  • Route backend memakai global prefix /api, jadi endpoint controller GET /webhooks/whatsapp menjadi GET /api/webhooks/whatsapp.
  • Di production, nginx mengekspos backend internal aplikasi lewat prefix https://portal.bizone.id/backend-api.
  • Prefix /api/* di browser dipakai oleh route handler Next.js untuk operasi dashboard seperti save contact, save user, export, dan aksi client-side lain.
  • Jika Anda ingin verifikasi tanda tangan resmi dari Meta, isi META_WEBHOOK_APP_SECRET.
  • Bila META_WEBHOOK_APP_SECRET terisi, request ke POST /api/webhooks/whatsapp/meta menuntut header x-hub-signature-256.
  • Endpoint POST /api/webhooks/whatsapp tetap bisa dipakai untuk Meta bila Anda memilih verify token + shared secret non-Meta untuk test lain, tetapi untuk produksi Meta lebih aman menargetkan URL default callback dan menyimpan META_WEBHOOK_APP_SECRET.

1. DNS

Buat A record:

  • portal.bizone.id -> IP publik server Debian 12

Pastikan propagasi selesai sebelum minta sertifikat TLS.

2. Install paket dasar

sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx curl git build-essential
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER

Logout lalu login ulang setelah menambahkan grup docker.

Verifikasi:

node -v
npm -v
docker --version
docker compose version

3. Siapkan user dan direktori aplikasi

sudo useradd -m -s /bin/bash bizone
sudo mkdir -p /srv
sudo chown -R $USER:$USER /srv
cd /srv
git clone https://git.iptek.co/wirabasalamah/BizOne-portal.git bizone-web
cd /srv/bizone-web

Jika repo dikirim manual:

sudo mkdir -p /srv/bizone-web
sudo chown -R $USER:$USER /srv/bizone-web

Lalu salin source code ke /srv/bizone-web.

4. Install dependency dan build

Root dependency Prisma:

cd /srv/bizone-web
npm install

Jangan lewati langkah root ini. Script backend/npm run db:generate mengambil Prisma client hasil generate dari root repo.

Backend:

cd /srv/bizone-web/backend
npm install
npm run db:generate
npm run build

Jika Anda langsung menjalankan npm run build tanpa npm run db:generate, TypeScript biasanya gagal dengan error seperti Prisma.sql does not exist, Prisma.InputJsonValue, atau model Prisma tidak ditemukan.

Frontend:

cd /srv/bizone-web/frontend
npm install
npm run build

5. Siapkan .env production

Salin template:

cp /srv/bizone-web/deploy/debian12/app.env.example /srv/bizone-web/.env

Lalu ubah semua placeholder, terutama:

  • DATABASE_URL
  • JWT_SECRET
  • JWT_REFRESH_SECRET
  • WEBHOOK_VERIFY_TOKEN
  • WEBHOOK_SHARED_SECRET
  • META_WEBHOOK_APP_SECRET
  • MAIL_*

Nilai yang wajib dipakai untuk domain ini:

NODE_ENV=production
FRONTEND_ORIGIN=https://portal.bizone.id
PUBLIC_API_URL=https://portal.bizone.id
NEXT_PUBLIC_API_URL=https://portal.bizone.id/api
PORT=3001
WEBHOOK_ALLOW_UNSIGNED=false

Generate secret aman:

openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32

Gunakan hasil berbeda untuk:

  • JWT_SECRET
  • JWT_REFRESH_SECRET
  • WEBHOOK_VERIFY_TOKEN
  • WEBHOOK_SHARED_SECRET

Sebelum menjalankan command Prisma atau backend secara manual, export env ke shell aktif:

cd /srv/bizone-web
set -a
source .env
set +a

Tanpa langkah ini, command seperti npm run db:migrate:deploy bisa gagal dengan error Environment variable not found: DATABASE_URL.

6. Jalankan PostgreSQL dan Redis

cd /srv/bizone-web/deploy/debian12
docker compose -f docker-compose.infra.yml up -d
docker compose -f docker-compose.infra.yml ps

7. Generate Prisma client dan migrasi database

cd /srv/bizone-web/backend
npm run db:generate
npm run db:migrate:deploy

Jika database masih kosong total, Anda bisa seed admin:

npm run seed:admin

Seed default saat ini:

  • Email: admin@bizone.id
  • Password: ChangeMe123!

Masuk lalu segera ganti password.

8. Pasang service systemd

Salin file service:

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/
sudo systemctl daemon-reload
sudo systemctl enable bizone-backend bizone-frontend
sudo systemctl start bizone-backend bizone-frontend

Cek status:

sudo systemctl status bizone-backend
sudo systemctl status bizone-frontend

Lihat log:

sudo journalctl -u bizone-backend -f
sudo journalctl -u bizone-frontend -f

9. Pasang nginx

Salin config:

sudo cp /srv/bizone-web/deploy/debian12/nginx.portal.bizone.id.conf /etc/nginx/sites-available/portal.bizone.id
sudo ln -s /etc/nginx/sites-available/portal.bizone.id /etc/nginx/sites-enabled/portal.bizone.id
sudo nginx -t
sudo systemctl reload nginx

Uji HTTP lokal:

curl -I http://portal.bizone.id
curl http://portal.bizone.id/api/health
curl http://portal.bizone.id/backend-api/health

10. Aktifkan HTTPS

sudo certbot --nginx -d portal.bizone.id

Setelah cert aktif, uji:

curl -I https://portal.bizone.id
curl https://portal.bizone.id/api/health
curl https://portal.bizone.id/backend-api/health

Respons health ideal:

{"status":"ok","service":"wa-dashboard-backend","database":"ok","timestamp":"..."}

11. Data Meta yang harus Anda masukkan

Di Meta App Dashboard / WhatsApp configuration:

  • Callback URL: https://portal.bizone.id/api/webhooks/whatsapp
  • Verify token: isi dengan nilai WEBHOOK_VERIFY_TOKEN

Jika Anda menyimpan META_WEBHOOK_APP_SECRET, backend akan memverifikasi signature event masuk dari header x-hub-signature-256.

Subscription event yang relevan untuk aplikasi ini:

  • messages
  • message_deliveries
  • message_read
  • message_sent
  • message_failed
  • template_category_update
  • account_update

Mapping internal saat ini:

  • messages -> message.inbound
  • message_deliveries -> message.delivered
  • message_read -> message.read
  • message_sent -> message.sent
  • message_failed -> message.failed
  • template_category_update -> template.updated
  • account_update -> account.updated

12. Urutan test live yang saya sarankan

  1. Pastikan https://portal.bizone.id/api/health mengembalikan 200.
  2. Coba buka https://portal.bizone.id.
  3. Lakukan webhook verification dari Meta dengan callback URL production.
  4. Kirim test webhook dari Meta.
  5. Login ke dashboard dan buka Dashboard > Webhooks Logs.
  6. Kirim pesan WhatsApp sungguhan ke nomor bisnis yang terhubung.
  7. Pastikan inbound message masuk ke inbox conversation.
  8. Balas dari dashboard bila access token dan phoneNumberId sudah terisi.
  9. Cek status sent, delivered, read, atau failed kembali masuk lewat webhook.

13. Command update deploy berikutnya

Setelah ada perubahan code:

cd /srv/bizone-web
git pull
npm install
set -a
source .env
set +a
cd backend && npm install && npm run db:generate && npm run build && npm run db:migrate:deploy
cd ../frontend && npm install && npm run build
sudo systemctl restart bizone-backend bizone-frontend

Jika server belum punya identity Git dan Anda ingin commit langsung dari server:

git config user.name "Wira Irawan"
git config user.email "wira.irawan@gmail.com"

14. Smoke check minimal

curl https://portal.bizone.id/api/health
curl -I https://portal.bizone.id
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

##+Q&xN$86LbSA<av< Ganti NEXT_PUBLIC_API_URL production menjadi:

NEXT_PUBLIC_API_URL=https://portal.bizone.id/backend-api

Ini penting agar frontend server-side berbicara ke backend asli, sementara browser tetap bisa memakai route handler Next.js di /api/*.