375 lines
10 KiB
Markdown
375 lines
10 KiB
Markdown
# 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`
|
|
- Midtrans notification URL: `https://portal.bizone.id/api/wallet/midtrans/notification`
|
|
- 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.
|
|
- Karena prefix `/api/*` sebagian dipakai Next.js, nginx hanya meneruskan endpoint backend publik yang perlu dipanggil pihak luar: `/api/health`, `/api/webhooks/*`, dan `/api/wallet/midtrans/*`.
|
|
- 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
|
|
INTERNAL_API_URL=http://127.0.0.1:3001/api
|
|
NEXT_PUBLIC_API_URL=https://portal.bizone.id/backend-api
|
|
PORT=3001
|
|
WEBHOOK_ALLOW_UNSIGNED=false
|
|
MIDTRANS_ALLOWED_PAYMENT_TYPES=gopay,shopeepay,bank_transfer,credit_card
|
|
```
|
|
|
|
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`
|
|
|
|
Tambahkan credential provider sesuai dashboard masing-masing:
|
|
|
|
- `META_WEBHOOK_APP_SECRET` dari Meta App Dashboard.
|
|
- `MIDTRANS_SERVER_KEY`, `MIDTRANS_CLIENT_KEY`, dan `MIDTRANS_MERCHANT_ID` dari Midtrans Dashboard.
|
|
- `MIDTRANS_ENV=sandbox` untuk sandbox key, atau `MIDTRANS_ENV=production` untuk production key.
|
|
|
|
Sebelum menjalankan command Prisma atau backend secara manual, export env ke shell aktif:
|
|
|
|
```bash
|
|
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
|
|
|
|
```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
|
|
curl http://portal.bizone.id/backend-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
|
|
curl https://portal.bizone.id/backend-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. Data Midtrans yang harus Anda masukkan
|
|
|
|
Di Midtrans Dashboard, set notification URL:
|
|
|
|
```text
|
|
https://portal.bizone.id/api/wallet/midtrans/notification
|
|
```
|
|
|
|
Payment channel yang disarankan untuk wallet top up:
|
|
|
|
- GoPay/QRIS
|
|
- ShopeePay
|
|
- Bank Transfer / Virtual Account
|
|
- Credit Card
|
|
|
|
Env aplikasi:
|
|
|
|
```dotenv
|
|
MIDTRANS_ENV=sandbox
|
|
MIDTRANS_ALLOWED_PAYMENT_TYPES=gopay,shopeepay,bank_transfer,credit_card
|
|
```
|
|
|
|
Gunakan `MIDTRANS_ENV=production` hanya jika key yang dipasang adalah production key.
|
|
|
|
## 13. 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.
|
|
10. Buat top up wallet dari `Dashboard > Wallet`.
|
|
11. Selesaikan pembayaran sandbox Midtrans.
|
|
12. Pastikan notification Midtrans mengubah payment order menjadi `paid` dan saldo wallet bertambah.
|
|
|
|
## 14. Command update deploy berikutnya
|
|
|
|
Setelah ada perubahan code:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
git config user.name "Wira Irawan"
|
|
git config user.email "wira.irawan@gmail.com"
|
|
```
|
|
|
|
## 15. 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
|
|
```
|