473 lines
10 KiB
Markdown
473 lines
10 KiB
Markdown
# Deploy Production
|
||
|
||
Dokumen ini menyiapkan deploy production untuk:
|
||
|
||
- 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`
|
||
|
||
## 1. Persiapan Server
|
||
|
||
Siapkan:
|
||
|
||
- Node.js LTS
|
||
- npm
|
||
- PostgreSQL
|
||
- nginx
|
||
- certbot / SSL Let’s Encrypt
|
||
|
||
Direktori contoh:
|
||
|
||
```bash
|
||
/var/www/abelbirdnest-web
|
||
```
|
||
|
||
## 2. Buat User Khusus Aplikasi
|
||
|
||
Jalankan sebagai `root` atau dengan `sudo`:
|
||
|
||
```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
|
||
```
|
||
|
||
Catatan:
|
||
|
||
- user `abelbirdnest` dipakai khusus untuk menjalankan service aplikasi
|
||
- jangan jalankan app production dengan user pribadi atau `root`
|
||
|
||
## 3. Clone Repo dari Git
|
||
|
||
Masuk sebagai user aplikasi:
|
||
|
||
```bash
|
||
sudo -u abelbirdnest -H bash
|
||
cd /var/www/abelbirdnest-web
|
||
git clone https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git .
|
||
```
|
||
|
||
Kalau server butuh autentikasi git internal, siapkan credential sesuai kebijakan server Git Anda.
|
||
|
||
## 4. Environment Production
|
||
|
||
Salin `.env.production.example` menjadi `.env.production`, lalu isi nilainya.
|
||
|
||
Yang wajib:
|
||
|
||
```env
|
||
NODE_ENV=production
|
||
PORT=3007
|
||
APP_URL=https://abelbirdnest.id
|
||
DATABASE_URL=postgresql://...
|
||
AUTH_SECRET=...
|
||
AUTH_BOOTSTRAP=false
|
||
SMTP_HOST=...
|
||
SMTP_PORT=465
|
||
SMTP_SECURE=true
|
||
SMTP_USER=...
|
||
SMTP_PASSWORD=...
|
||
SMTP_FROM=...
|
||
```
|
||
|
||
Catatan:
|
||
|
||
- `AUTH_SECRET` harus random panjang.
|
||
- `AUTH_BOOTSTRAP=false` wajib untuk production.
|
||
- `APP_URL` harus domain production final.
|
||
|
||
## 5. Inisialisasi Database PostgreSQL
|
||
|
||
Contoh di bawah memakai:
|
||
|
||
- database: `abelbirdnest_prod`
|
||
- database user: `abelbirdnest_app`
|
||
- host: `127.0.0.1`
|
||
- port: `5432`
|
||
|
||
Masuk ke PostgreSQL sebagai superuser:
|
||
|
||
```bash
|
||
sudo -u postgres psql
|
||
```
|
||
|
||
Buat user database:
|
||
|
||
```sql
|
||
CREATE USER abelbirdnest_app WITH PASSWORD '72ed04ddd2bb520eacae7f4b71a16b0d';
|
||
```
|
||
|
||
Buat database production:
|
||
|
||
```sql
|
||
CREATE DATABASE abelbirdnest_prod OWNER abelbirdnest_app;
|
||
```
|
||
|
||
Pastikan owner database benar:
|
||
|
||
```sql
|
||
ALTER DATABASE abelbirdnest_prod OWNER TO abelbirdnest_app;
|
||
```
|
||
|
||
Opsional tapi disarankan, kunci privilege default:
|
||
|
||
```sql
|
||
REVOKE ALL ON DATABASE abelbirdnest_prod FROM PUBLIC;
|
||
GRANT ALL PRIVILEGES ON DATABASE abelbirdnest_prod TO abelbirdnest_app;
|
||
```
|
||
|
||
Keluar dari `psql`:
|
||
|
||
```sql
|
||
\q
|
||
```
|
||
|
||
Tes koneksi:
|
||
|
||
```bash
|
||
psql "postgresql://abelbirdnest_app:72ed04ddd2bb520eacae7f4b71a16b0d@127.0.0.1:5432/abelbirdnest_prod?schema=public"
|
||
```
|
||
|
||
Jika koneksi berhasil, pakai URL itu di `.env.production`:
|
||
|
||
```env
|
||
DATABASE_URL="postgresql://abelbirdnest_app:ganti-dengan-password-yang-kuat@127.0.0.1:5432/abelbirdnest_prod?schema=public"
|
||
```
|
||
|
||
## 6. Install Dependency, Database & Migration
|
||
|
||
Repo ini sudah disiapkan memakai migration Prisma.
|
||
|
||
Jalankan:
|
||
|
||
```bash
|
||
cd /var/www/abelbirdnest-web
|
||
npm install
|
||
npm run prisma:generate
|
||
npm run prisma:migrate:deploy
|
||
```
|
||
|
||
Kalau perlu isi master awal:
|
||
|
||
```bash
|
||
npm run seed:master
|
||
```
|
||
|
||
Data seed yang dibawa:
|
||
|
||
- grade
|
||
- bank
|
||
- currency
|
||
|
||
Urutan pertama kali untuk fresh database:
|
||
|
||
```bash
|
||
cd /var/www/abelbirdnest-web
|
||
npm install
|
||
npm run prisma:generate
|
||
npm run prisma:migrate:deploy
|
||
npm run seed:master
|
||
```
|
||
|
||
Catatan:
|
||
|
||
- `prisma:migrate:deploy` akan membuat seluruh tabel dari migration yang ada di repo
|
||
- `seed:master` hanya mengisi data awal `grade`, `bank`, dan `currency`
|
||
- user login production tetap harus dibuat terpisah, jangan mengandalkan akun dev/default
|
||
|
||
## 7. User Login Awal Production
|
||
|
||
Sistem login tidak punya user production bawaan permanen.
|
||
|
||
Di kode memang ada akun default, tetapi akun itu hanya dibuat jika:
|
||
|
||
```env
|
||
AUTH_BOOTSTRAP=true
|
||
```
|
||
|
||
Jika production langsung memakai:
|
||
|
||
```env
|
||
AUTH_BOOTSTRAP=false
|
||
```
|
||
|
||
maka akun login awal tidak akan ada.
|
||
|
||
### Opsi yang paling praktis: bootstrap sementara
|
||
|
||
1. Ubah `.env.production` sementara menjadi:
|
||
|
||
```env
|
||
AUTH_BOOTSTRAP=true
|
||
```
|
||
|
||
2. Build dan jalankan aplikasi:
|
||
|
||
```bash
|
||
cd /var/www/abelbirdnest-web
|
||
npm run build
|
||
sudo systemctl restart abelbirdnest-web
|
||
```
|
||
|
||
3. Login pertama kali lewat:
|
||
|
||
- web: `https://abelbirdnest.id/login`
|
||
- API: `POST /api/v1/auth/login`
|
||
|
||
Identity bisa memakai `email` atau `username`.
|
||
|
||
4. Akun default yang akan tersedia saat bootstrap aktif:
|
||
|
||
- `admin` / `admin123`
|
||
- `owner` / `owner123`
|
||
- `purchasing` / `purchasing123`
|
||
- `warehouse` / `warehouse123`
|
||
- `qc` / `qc123`
|
||
- `sales` / `sales123`
|
||
|
||
Email default:
|
||
|
||
- `admin@abelbirdnest.local`
|
||
- `owner@abelbirdnest.local`
|
||
- `purchasing@abelbirdnest.local`
|
||
- `warehouse@abelbirdnest.local`
|
||
- `qc@abelbirdnest.local`
|
||
- `sales@abelbirdnest.local`
|
||
|
||
5. Setelah berhasil login, segera buat user production final dari menu `Users`.
|
||
|
||
Minimal disarankan:
|
||
|
||
- 1 user `SYSTEM_ADMIN` atau `ADMIN`
|
||
- 1 user `OWNER`
|
||
- user operasional sesuai kebutuhan: `PURCHASING`, `WAREHOUSE`, `QC`, `SALES`
|
||
|
||
6. Setelah user production final selesai dibuat dan sudah dites login:
|
||
|
||
- ubah lagi `.env.production` menjadi:
|
||
|
||
```env
|
||
AUTH_BOOTSTRAP=false
|
||
```
|
||
|
||
- restart service:
|
||
|
||
```bash
|
||
sudo systemctl restart abelbirdnest-web
|
||
```
|
||
|
||
7. Opsional tapi sangat disarankan:
|
||
|
||
- nonaktifkan atau hapus akun default bootstrap dari menu `Users`
|
||
- ganti semua password default jika akun tersebut tetap dipertahankan sementara
|
||
|
||
### Catatan keamanan
|
||
|
||
- Jangan biarkan `AUTH_BOOTSTRAP=true` aktif terus di production.
|
||
- Jangan gunakan password default untuk operasi harian.
|
||
- Setelah bootstrap selesai, verifikasi bahwa login masih normal memakai user production yang baru dibuat.
|
||
|
||
## 8. Build Production
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
## 9. Jalankan App di Port 3007
|
||
|
||
Manual:
|
||
|
||
```bash
|
||
PORT=3007 npm run start
|
||
```
|
||
|
||
Atau gunakan `systemd` dari:
|
||
|
||
```bash
|
||
deploy/systemd/abelbirdnest-web.service
|
||
```
|
||
|
||
Contoh setup:
|
||
|
||
```bash
|
||
sudo cp deploy/systemd/abelbirdnest-web.service /etc/systemd/system/
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable abelbirdnest-web
|
||
sudo systemctl start abelbirdnest-web
|
||
sudo systemctl status abelbirdnest-web
|
||
```
|
||
|
||
Autostart saat server restart terjadi karena service di-`enable`.
|
||
|
||
Untuk verifikasi:
|
||
|
||
```bash
|
||
sudo systemctl is-enabled abelbirdnest-web
|
||
```
|
||
|
||
## 10. Reverse Proxy Nginx
|
||
|
||
Gunakan file:
|
||
|
||
```bash
|
||
deploy/nginx/abelbirdnest.id.conf
|
||
```
|
||
|
||
Pasang:
|
||
|
||
```bash
|
||
sudo cp deploy/nginx/abelbirdnest.id.conf /etc/nginx/sites-available/abelbirdnest.id.conf
|
||
sudo ln -s /etc/nginx/sites-available/abelbirdnest.id.conf /etc/nginx/sites-enabled/abelbirdnest.id.conf
|
||
sudo nginx -t
|
||
sudo systemctl reload nginx
|
||
```
|
||
|
||
## 11. Health Check
|
||
|
||
Endpoint health:
|
||
|
||
```bash
|
||
GET /api/v1/health
|
||
```
|
||
|
||
Contoh:
|
||
|
||
```bash
|
||
curl https://abelbirdnest.id/api/v1/health
|
||
```
|
||
|
||
## 12. Update Deployment Berikutnya
|
||
|
||
Jika aplikasi sudah live dan ada update dari git:
|
||
|
||
```bash
|
||
cd /var/www/abelbirdnest-web
|
||
git pull origin main
|
||
npm install
|
||
npm run prisma:migrate:deploy
|
||
npm run build
|
||
sudo systemctl restart abelbirdnest-web
|
||
```
|
||
|
||
## 13. Alternatif Deploy: Build di Lokal, Jalankan di Server
|
||
|
||
Repo ini sekarang mendukung output Next.js `standalone`, sehingga build dilakukan di lingkungan Linux lokal/container lalu artifact di-upload ke server. Server production tidak menjalankan `npm run build`.
|
||
|
||
### Kapan jalur ini dipakai
|
||
|
||
Pakai cara ini jika:
|
||
|
||
- server production terlalu kecil untuk `next build`
|
||
- build sering mati karena RAM habis
|
||
- Anda ingin memisahkan proses build dan runtime
|
||
|
||
### Prasyarat
|
||
|
||
- build harus dilakukan di Linux Alpine, atau container Linux Alpine
|
||
- versi Node saat build harus sama dengan server
|
||
- server Alpine perlu `nodejs` dan `openssl` terpasang
|
||
- untuk server RAM 1 GB, runtime disarankan memakai `NODE_OPTIONS=--max-old-space-size=512`
|
||
- database migration tetap dijalankan di server
|
||
|
||
### Script yang disediakan
|
||
|
||
Build artifact Linux:
|
||
|
||
```bash
|
||
deploy/scripts/build-linux-release.sh
|
||
```
|
||
|
||
Upload artifact ke server:
|
||
|
||
```bash
|
||
deploy/scripts/upload-linux-release.sh
|
||
```
|
||
|
||
### Contoh build artifact di lokal
|
||
|
||
Pastikan Docker tersedia di mesin lokal/build machine. Script default memakai image `node:20-alpine` agar artifact cocok dengan server Alpine Linux. `.env.production` production tetap disimpan di server, bukan dibawa di artifact.
|
||
|
||
```bash
|
||
./deploy/scripts/build-linux-release.sh
|
||
```
|
||
|
||
Artifact default yang dihasilkan memakai timestamp:
|
||
|
||
```bash
|
||
abelbirdnest-release-YYYYMMDD-HHMMSS.tar.gz
|
||
```
|
||
|
||
Isi artifact:
|
||
|
||
- server Next.js standalone
|
||
- static assets `.next/static`
|
||
- folder `public`
|
||
- folder `prisma`
|
||
- tidak membawa `.env.production`
|
||
|
||
### Contoh upload ke server
|
||
|
||
```bash
|
||
./deploy/scripts/upload-linux-release.sh abelbirdnest@server /var/www/abelbirdnest-web/AbelBirdNest-Stock
|
||
```
|
||
|
||
Setelah upload, script akan:
|
||
|
||
- copy artifact ke server
|
||
- extract ke `/var/www/abelbirdnest-web/AbelBirdNest-Stock/releases/<timestamp>`
|
||
- update symlink `/var/www/abelbirdnest-web/AbelBirdNest-Stock/current`
|
||
|
||
### Langkah setelah upload di server
|
||
|
||
Masuk ke server:
|
||
|
||
```bash
|
||
ssh abelbirdnest@server
|
||
cd /var/www/abelbirdnest-web/AbelBirdNest-Stock/current
|
||
```
|
||
|
||
Artifact standalone dibuat untuk runtime. Jangan menjalankan `npm install`, `npm run build`, atau `prisma migrate deploy` di server kecil. Jika rilis membawa migration database, jalankan migration dari mesin build/admin yang punya dependency lengkap dan akses ke database production.
|
||
|
||
Untuk menjalankan standalone app secara manual:
|
||
|
||
```bash
|
||
PORT=3007 node server.js
|
||
```
|
||
|
||
Jika memakai `systemd`, `WorkingDirectory` service harus diarahkan ke:
|
||
|
||
```bash
|
||
/var/www/abelbirdnest-web/AbelBirdNest-Stock/current
|
||
```
|
||
|
||
dan `ExecStart` menjadi:
|
||
|
||
```bash
|
||
/usr/bin/node server.js
|
||
```
|
||
|
||
Jika branch utama nanti bukan `main`, sesuaikan perintah `git pull`.
|
||
|
||
## 12. Checklist Go-Live
|
||
|
||
- `AUTH_BOOTSTRAP=false`
|
||
- `AUTH_SECRET` sudah production-grade
|
||
- `APP_URL=https://abelbirdnest.id`
|
||
- SSL aktif
|
||
- database backup aktif
|
||
- `npm run build` lulus
|
||
- `npm run prisma:migrate:deploy` lulus
|
||
- `npm run seed:master` selesai jika dibutuhkan
|
||
- login, reset password, dan email verifikasi sudah dites
|
||
- create purchase, receipt, lot, sale sudah dites
|
||
|
||
## 13. Catatan Penting
|
||
|
||
- Jangan pakai `npm run db:push` untuk production.
|
||
- Jangan pakai akun default development.
|
||
- Jangan simpan `.env.production` di repo.
|
||
- Pastikan ownership file tetap `abelbirdnest:abelbirdnest`.
|