# 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 public base URL: `https://portal.bizone.id/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`. - 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 ```bash 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: ```bash node -v npm -v docker --version docker compose version ``` ## 3. Siapkan user dan direktori aplikasi ```bash 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: ```bash 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: ```bash 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: ```bash 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: ```bash cd /srv/bizone-web/frontend npm install npm run build ``` ## 5. Siapkan `.env` production Salin template: ```bash 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: ```dotenv 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: ```bash 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` ## 6. Jalankan PostgreSQL dan Redis ```bash 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 ```bash cd /srv/bizone-web/backend npm run db:generate npm run db:migrate:deploy ``` Jika database masih kosong total, Anda bisa seed admin: ```bash 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: ```bash 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: ```bash sudo systemctl status bizone-backend sudo systemctl status bizone-frontend ``` Lihat log: ```bash sudo journalctl -u bizone-backend -f sudo journalctl -u bizone-frontend -f ``` ## 9. Pasang `nginx` Salin config: ```bash 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: ```bash curl -I http://portal.bizone.id curl http://portal.bizone.id/api/health ``` ## 10. Aktifkan HTTPS ```bash sudo certbot --nginx -d portal.bizone.id ``` Setelah cert aktif, uji: ```bash curl -I https://portal.bizone.id curl https://portal.bizone.id/api/health ``` Respons health ideal: ```json {"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: ```bash cd /srv/bizone-web git pull npm install cd backend && npm install && npm run build && npm run db:generate && 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: ```bash git config user.name "Wira Irawan" git config user.email "wira.irawan@gmail.com" ``` ## 14. Smoke check minimal ```bash 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 ```