Files
AbelBirdNest-Stock/docs/deploy-production.md

415 lines
7.7 KiB
Markdown

# Deploy Production
Panduan ini untuk deploy production dengan asumsi:
- domain `abelbirdnest.id`
- reverse proxy `nginx`
- aplikasi Next.js di port `3007`
- database `PostgreSQL`
- source code dari git `https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git`
- user service khusus `abelbirdnest`
- repo berada di:
`/var/www/abelbirdnest-web/AbelBirdNest-Stock`
## 1. Persiapan Server
Install:
- Node.js LTS
- npm
- PostgreSQL
- nginx
- certbot
Direktori aplikasi:
```bash
/var/www/abelbirdnest-web
```
## 2. Buat User OS Khusus Aplikasi
```bash
sudo useradd -r -m -d /var/www/abelbirdnest-web -s /bin/bash abelbirdnest
sudo mkdir -p /var/www/abelbirdnest-web
sudo chown -R abelbirdnest:abelbirdnest /var/www/abelbirdnest-web
```
Masuk sebagai user aplikasi:
```bash
sudo -u abelbirdnest -H bash
cd /var/www/abelbirdnest-web
```
## 3. Clone Repo
Clone normal:
```bash
git clone https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock
```
Catatan:
- panduan ini mengikuti struktur clone normal di atas
- jadi `WorkingDirectory`, `.env.production`, dan semua perintah memakai path:
`/var/www/abelbirdnest-web/AbelBirdNest-Stock`
## 4. Siapkan Environment Production
Salin file contoh:
```bash
cp .env.production.example .env.production
```
Isi minimal:
```env
NODE_ENV=production
PORT=3007
APP_URL=https://abelbirdnest.id
DATABASE_URL=postgresql://abelbirdnest_app:password@127.0.0.1:5432/abelbirdnest_prod?schema=public
AUTH_SECRET=ganti-dengan-random-string-panjang
AUTH_BOOTSTRAP=false
SMTP_HOST=...
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=...
SMTP_PASSWORD=...
SMTP_FROM=...
```
Catatan:
- `AUTH_BOOTSTRAP=false` wajib di production
- akun default dev tidak akan aktif
- `AUTH_SECRET` harus random dan panjang
## 5. Inisialisasi PostgreSQL
Masuk sebagai superuser PostgreSQL:
```bash
sudo -u postgres psql
```
Buat user database:
```sql
CREATE USER abelbirdnest_app WITH PASSWORD 'ganti-dengan-password-yang-kuat';
```
Buat database:
```sql
CREATE DATABASE abelbirdnest_prod OWNER abelbirdnest_app;
ALTER DATABASE abelbirdnest_prod OWNER TO abelbirdnest_app;
REVOKE ALL ON DATABASE abelbirdnest_prod FROM PUBLIC;
GRANT ALL PRIVILEGES ON DATABASE abelbirdnest_prod TO abelbirdnest_app;
```
Keluar:
```sql
\q
```
Tes koneksi:
```bash
psql "postgresql://abelbirdnest_app:ganti-dengan-password-yang-kuat@127.0.0.1:5432/abelbirdnest_prod"
```
Catatan:
- untuk `psql`, jangan pakai `?schema=public`
- untuk `DATABASE_URL` Prisma, tetap pakai `?schema=public`
## 6. Install Dependency dan Buat Tabel
Masih sebagai user `abelbirdnest`:
```bash
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock
npm install
npm run prisma:generate
```
Load env production ke shell saat menjalankan command manual:
```bash
set -a
source .env.production
set +a
```
Jalankan migration:
```bash
npm run prisma:migrate:deploy
```
Opsional cek status:
```bash
npx prisma migrate status
```
## 7. Seed Data Awal
Untuk fresh database:
```bash
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock
set -a
source .env.production
set +a
npm run seed:banks
npm run seed:currencies
```
### Khusus Grade
`seed:grades` butuh file `Grade.xls`.
Buat folder data:
```bash
mkdir -p scripts/data
```
Upload file `Grade.xls` ke:
```bash
/var/www/abelbirdnest-web/AbelBirdNest-Stock/scripts/data/Grade.xls
```
Lalu jalankan:
```bash
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock
set -a
source .env.production
set +a
npm run seed:grades
```
Alternatif jika file ada di lokasi lain:
```bash
node scripts/seed-grades-from-xls.mjs /path/ke/Grade.xls
```
## 8. Buat User Pertama di PostgreSQL
Karena `AUTH_BOOTSTRAP=false`, Anda harus buat user login pertama sendiri.
### 8.1 Generate Hash Password
Ganti password contoh ini:
```bash
node -e 'const {randomBytes,scryptSync}=require("crypto"); const p="GantiPasswordKuat123!"; const salt=randomBytes(16).toString("hex"); const derived=scryptSync(p,salt,64).toString("hex"); console.log(`${salt}:${derived}`)'
```
Simpan output hash-nya.
### 8.2 Masuk ke PostgreSQL
```bash
psql "postgresql://abelbirdnest_app:password@127.0.0.1:5432/abelbirdnest_prod"
```
### 8.3 Pastikan Role `SYSTEM_ADMIN` Ada
```sql
INSERT INTO roles (code, name, created_at, updated_at)
VALUES ('SYSTEM_ADMIN', 'System Admin', NOW(), NOW())
ON CONFLICT (code) DO UPDATE
SET name = EXCLUDED.name,
updated_at = NOW();
```
### 8.4 Buat User Pertama
Ganti:
- `Nama Anda`
- `superadmin`
- `superadmin@abelbirdnest.id`
- `HASH_HASIL_LANGKAH_8_1`
```sql
INSERT INTO users (
role_id,
name,
username,
email,
email_verified_at,
phone,
password_hash,
status,
created_at,
updated_at
)
SELECT
r.id,
'Nama Anda',
'superadmin',
'superadmin@abelbirdnest.id',
NOW(),
NULL,
'HASH_HASIL_LANGKAH_8_1',
'ACTIVE',
NOW(),
NOW()
FROM roles r
WHERE r.code = 'SYSTEM_ADMIN'
ON CONFLICT (email) DO UPDATE
SET role_id = EXCLUDED.role_id,
name = EXCLUDED.name,
username = EXCLUDED.username,
email_verified_at = EXCLUDED.email_verified_at,
password_hash = EXCLUDED.password_hash,
status = EXCLUDED.status,
updated_at = NOW();
```
Verifikasi:
```sql
SELECT u.id, u.name, u.username, u.email, u.status, r.code AS role
FROM users u
JOIN roles r ON r.id = u.role_id
WHERE u.email = 'superadmin@abelbirdnest.id';
```
## 9. Build Production
```bash
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock
set -a
source .env.production
set +a
npm run build
```
## 10. Jalankan App dengan systemd
File service repo sudah disiapkan untuk struktur subfolder ini:
```bash
deploy/systemd/abelbirdnest-web.service
```
Pasang:
```bash
sudo cp /var/www/abelbirdnest-web/AbelBirdNest-Stock/deploy/systemd/abelbirdnest-web.service /etc/systemd/system/
sudo chown -R abelbirdnest:abelbirdnest /var/www/abelbirdnest-web/AbelBirdNest-Stock
sudo systemctl daemon-reload
sudo systemctl enable abelbirdnest-web
sudo systemctl restart abelbirdnest-web
sudo systemctl status abelbirdnest-web
```
Verifikasi port:
```bash
ss -ltnp | grep 3007
curl http://127.0.0.1:3007/api/v1/health
```
Kalau service gagal, cek:
```bash
sudo systemctl cat abelbirdnest-web
sudo journalctl -u abelbirdnest-web -n 100 --no-pager
which npm
```
## 11. Pasang Nginx Tahap 1: HTTP Dulu
Jangan langsung pakai config HTTPS sebelum sertifikat ada.
Pakai file ini dulu:
```bash
deploy/nginx/abelbirdnest.id.http.conf
```
Pasang:
```bash
sudo cp /var/www/abelbirdnest-web/AbelBirdNest-Stock/deploy/nginx/abelbirdnest.id.http.conf /etc/nginx/sites-available/abelbirdnest.id.conf
sudo ln -sf /etc/nginx/sites-available/abelbirdnest.id.conf /etc/nginx/sites-enabled/abelbirdnest.id.conf
sudo nginx -t
sudo systemctl reload nginx
```
Tes:
```bash
curl http://abelbirdnest.id/api/v1/health
```
## 12. Buat Sertifikat SSL
Setelah HTTP sudah hidup:
```bash
sudo certbot --nginx -d abelbirdnest.id -d www.abelbirdnest.id
```
## 13. Ganti ke Config HTTPS Final
Setelah sertifikat berhasil dibuat, baru pakai config final:
```bash
sudo cp /var/www/abelbirdnest-web/AbelBirdNest-Stock/deploy/nginx/abelbirdnest.id.conf /etc/nginx/sites-available/abelbirdnest.id.conf
sudo nginx -t
sudo systemctl reload nginx
```
Verifikasi:
```bash
curl https://abelbirdnest.id/api/v1/health
```
## 14. Update Deployment Berikutnya
```bash
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock
git pull origin main
set -a
source .env.production
set +a
npm install
npm run prisma:generate
npm run prisma:migrate:deploy
npm run build
sudo systemctl restart abelbirdnest-web
sudo systemctl status abelbirdnest-web
```
## 15. Smoke Test Setelah Live
Cek minimal:
- login dengan user `SYSTEM_ADMIN`
- dashboard terbuka
- health check OK
- buat master `bank`, `currency`, `grade` tampil
- buat transaksi sederhana
- logout/login ulang
- email reset/verifikasi jika SMTP sudah aktif