Document Debian low RAM production deploy
This commit is contained in:
529
docs/deploy-debian13-low-ram.md
Normal file
529
docs/deploy-debian13-low-ram.md
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
# Deploy Debian 13 Production Low RAM
|
||||||
|
|
||||||
|
Panduan ini mencatat langkah deploy production Abel Birdnest pada server Debian 13 kosong dengan RAM kecil. Jalur ini sudah terbukti bisa dipakai dengan mengaktifkan swap sebelum `next build`.
|
||||||
|
|
||||||
|
Target:
|
||||||
|
|
||||||
|
- Domain: `abelbirdnest.id`
|
||||||
|
- SSH port: `3853`
|
||||||
|
- App user: `abelbirdnest`
|
||||||
|
- App path: `/var/www/abelbirdnest-web`
|
||||||
|
- App port: `3007`
|
||||||
|
- Database: PostgreSQL lokal
|
||||||
|
- Reverse proxy: Nginx
|
||||||
|
- SSL: Let's Encrypt
|
||||||
|
|
||||||
|
## 1. Login Server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -p 3853 root@IP_SERVER
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika memakai user sudo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -p 3853 namauser@IP_SERVER
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. DNS
|
||||||
|
|
||||||
|
Pastikan DNS mengarah ke IP server:
|
||||||
|
|
||||||
|
```text
|
||||||
|
abelbirdnest.id A IP_SERVER
|
||||||
|
www.abelbirdnest.id A IP_SERVER
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek dari komputer lokal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dig +short abelbirdnest.id
|
||||||
|
dig +short www.abelbirdnest.id
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Install Paket Dasar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt full-upgrade -y
|
||||||
|
sudo apt install -y git curl ca-certificates build-essential nodejs npm postgresql postgresql-contrib nginx certbot python3-certbot-nginx ufw
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek versi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node -v
|
||||||
|
npm -v
|
||||||
|
psql --version
|
||||||
|
nginx -v
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Firewall
|
||||||
|
|
||||||
|
Karena SSH memakai port `3853`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ufw allow 3853/tcp
|
||||||
|
sudo ufw allow 'Nginx Full'
|
||||||
|
sudo ufw enable
|
||||||
|
sudo ufw status
|
||||||
|
```
|
||||||
|
|
||||||
|
Jangan tutup akses SSH lama sebelum login lewat port `3853` sudah terbukti berhasil.
|
||||||
|
|
||||||
|
## 5. Aktifkan Swap untuk Server RAM Rendah
|
||||||
|
|
||||||
|
Jika server hanya punya RAM kecil, `npm run build` bisa mati dengan pesan seperti:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Next.js build worker exited with code: null and signal: SIGKILL
|
||||||
|
```
|
||||||
|
|
||||||
|
Itu biasanya karena proses build kehabisan memori. Aktifkan swap sebelum build.
|
||||||
|
|
||||||
|
Swap 2 GB:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo fallocate -l 2G /swapfile
|
||||||
|
sudo chmod 600 /swapfile
|
||||||
|
sudo mkswap /swapfile
|
||||||
|
sudo swapon /swapfile
|
||||||
|
```
|
||||||
|
|
||||||
|
Buat permanen setelah reboot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
free -h
|
||||||
|
swapon --show
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika 2 GB masih kurang, ganti menjadi 4 GB:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo swapoff /swapfile
|
||||||
|
sudo rm /swapfile
|
||||||
|
sudo fallocate -l 4G /swapfile
|
||||||
|
sudo chmod 600 /swapfile
|
||||||
|
sudo mkswap /swapfile
|
||||||
|
sudo swapon /swapfile
|
||||||
|
free -h
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika `/etc/fstab` sudah berisi baris `/swapfile`, tidak perlu menambah baris lagi.
|
||||||
|
|
||||||
|
## 6. Buat User 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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. Clone Repo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u abelbirdnest -H bash
|
||||||
|
cd /var/www/abelbirdnest-web
|
||||||
|
git clone https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git .
|
||||||
|
git checkout main
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika Git meminta login atau token, gunakan credential Git internal yang berlaku.
|
||||||
|
|
||||||
|
## 8. Setup Database PostgreSQL
|
||||||
|
|
||||||
|
Generate password database:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rand -base64 32
|
||||||
|
```
|
||||||
|
|
||||||
|
Masuk PostgreSQL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u postgres psql
|
||||||
|
```
|
||||||
|
|
||||||
|
Buat user dan database. Ganti `GANTI_PASSWORD_DB_KUAT` dengan password yang dibuat tadi.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE USER abelbirdnest_app WITH PASSWORD 'GANTI_PASSWORD_DB_KUAT';
|
||||||
|
CREATE DATABASE abelbirdnest_prod OWNER abelbirdnest_app;
|
||||||
|
REVOKE ALL ON DATABASE abelbirdnest_prod FROM PUBLIC;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE abelbirdnest_prod TO abelbirdnest_app;
|
||||||
|
\q
|
||||||
|
```
|
||||||
|
|
||||||
|
Tes koneksi:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql "postgresql://abelbirdnest_app:GANTI_PASSWORD_DB_KUAT@127.0.0.1:5432/abelbirdnest_prod?schema=public"
|
||||||
|
```
|
||||||
|
|
||||||
|
Keluar dari prompt `psql`:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
\q
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. Buat Environment Production
|
||||||
|
|
||||||
|
Generate secret:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rand -base64 48
|
||||||
|
```
|
||||||
|
|
||||||
|
Buat file env:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u abelbirdnest nano /var/www/abelbirdnest-web/.env.production
|
||||||
|
```
|
||||||
|
|
||||||
|
Isi:
|
||||||
|
|
||||||
|
```env
|
||||||
|
NODE_ENV=production
|
||||||
|
PORT=3007
|
||||||
|
APP_URL=https://abelbirdnest.id
|
||||||
|
DATABASE_URL="postgresql://abelbirdnest_app:GANTI_PASSWORD_DB_KUAT@127.0.0.1:5432/abelbirdnest_prod?schema=public"
|
||||||
|
AUTH_SECRET="GANTI_DENGAN_HASIL_OPENSSL"
|
||||||
|
AUTH_BOOTSTRAP=false
|
||||||
|
|
||||||
|
SMTP_HOST=
|
||||||
|
SMTP_PORT=465
|
||||||
|
SMTP_SECURE=true
|
||||||
|
SMTP_USER=
|
||||||
|
SMTP_PASSWORD=
|
||||||
|
SMTP_FROM="Abel Birdnest <no-reply@abelbirdnest.id>"
|
||||||
|
|
||||||
|
NEXT_PUBLIC_API_BASE_URL=
|
||||||
|
```
|
||||||
|
|
||||||
|
Kunci permission:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo chown abelbirdnest:abelbirdnest /var/www/abelbirdnest-web/.env.production
|
||||||
|
sudo chmod 600 /var/www/abelbirdnest-web/.env.production
|
||||||
|
```
|
||||||
|
|
||||||
|
## 10. Install Dependency, Migration, dan Seed Master
|
||||||
|
|
||||||
|
Prisma CLI perlu `DATABASE_URL`. Karena `.env.production` tidak selalu otomatis dibaca oleh perintah Prisma, load env sebelum migration dan seed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u abelbirdnest -H bash
|
||||||
|
cd /var/www/abelbirdnest-web
|
||||||
|
set -a
|
||||||
|
source .env.production
|
||||||
|
set +a
|
||||||
|
npm install
|
||||||
|
npm run prisma:generate
|
||||||
|
npm run prisma:migrate:deploy
|
||||||
|
npm run seed:master
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
`npm run seed:master` mengisi:
|
||||||
|
|
||||||
|
- currency
|
||||||
|
- grade
|
||||||
|
- bank
|
||||||
|
|
||||||
|
Jika muncul error:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Environment variable not found: DATABASE_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
Artinya env belum ter-load. Ulangi dari:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
set -a
|
||||||
|
source .env.production
|
||||||
|
set +a
|
||||||
|
```
|
||||||
|
|
||||||
|
Lalu cek:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "$DATABASE_URL" | sed 's/:.*@/:***@/'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 11. Seed Admin Awal
|
||||||
|
|
||||||
|
Jalankan script superadmin setelah migration selesai:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u abelbirdnest -H bash
|
||||||
|
cd /var/www/abelbirdnest-web
|
||||||
|
set -a
|
||||||
|
source .env.production
|
||||||
|
set +a
|
||||||
|
node scripts/seed-local-superadmin.mjs
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
User yang dibuat:
|
||||||
|
|
||||||
|
```text
|
||||||
|
email: wirabasalamah@gmail.com
|
||||||
|
username: wirabasalamah
|
||||||
|
password: password
|
||||||
|
role: SYSTEM_ADMIN
|
||||||
|
```
|
||||||
|
|
||||||
|
Setelah login pertama, segera ganti password.
|
||||||
|
|
||||||
|
## 12. Build Production pada RAM Rendah
|
||||||
|
|
||||||
|
Pastikan swap aktif:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
free -h
|
||||||
|
swapon --show
|
||||||
|
```
|
||||||
|
|
||||||
|
Build dengan limit memory Node:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u abelbirdnest -H bash
|
||||||
|
cd /var/www/abelbirdnest-web
|
||||||
|
set -a
|
||||||
|
source .env.production
|
||||||
|
set +a
|
||||||
|
NODE_OPTIONS=--max-old-space-size=1024 npm run build
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Jika masih mati dengan `SIGKILL`, cek OOM:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dmesg -T | tail -80
|
||||||
|
```
|
||||||
|
|
||||||
|
Cari baris `Out of memory`, `Killed process`, atau `node`. Jika ada, naikkan swap menjadi 4 GB lalu ulang build.
|
||||||
|
|
||||||
|
## 13. Setup systemd
|
||||||
|
|
||||||
|
Buat service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/systemd/system/abelbirdnest-web.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Isi:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=AbelBirdnest Stock Next.js
|
||||||
|
After=network.target postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/var/www/abelbirdnest-web
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
Environment=PORT=3007
|
||||||
|
Environment=NODE_OPTIONS=--max-old-space-size=512
|
||||||
|
EnvironmentFile=/var/www/abelbirdnest-web/.env.production
|
||||||
|
ExecStart=/usr/bin/npm run start
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
User=abelbirdnest
|
||||||
|
Group=abelbirdnest
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Start service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable abelbirdnest-web
|
||||||
|
sudo systemctl start abelbirdnest-web
|
||||||
|
sudo systemctl status abelbirdnest-web
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek lokal:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:3007/api/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 14. Setup Nginx HTTP
|
||||||
|
|
||||||
|
Buat config:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/nginx/sites-available/abelbirdnest.id.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Isi:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name abelbirdnest.id www.abelbirdnest.id;
|
||||||
|
|
||||||
|
client_max_body_size 20m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:3007;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto http;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_read_timeout 120s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ln -s /etc/nginx/sites-available/abelbirdnest.id.conf /etc/nginx/sites-enabled/abelbirdnest.id.conf
|
||||||
|
sudo nginx -t
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek HTTP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://abelbirdnest.id/api/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 15. Pasang SSL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo certbot --nginx -d abelbirdnest.id -d www.abelbirdnest.id
|
||||||
|
```
|
||||||
|
|
||||||
|
Pilih redirect HTTP ke HTTPS jika ditanya.
|
||||||
|
|
||||||
|
Tes renew:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo certbot renew --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek HTTPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://abelbirdnest.id/api/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 16. Login Pertama
|
||||||
|
|
||||||
|
Buka:
|
||||||
|
|
||||||
|
```text
|
||||||
|
https://abelbirdnest.id/login
|
||||||
|
```
|
||||||
|
|
||||||
|
Login:
|
||||||
|
|
||||||
|
```text
|
||||||
|
username/email: wirabasalamah atau wirabasalamah@gmail.com
|
||||||
|
password: password
|
||||||
|
```
|
||||||
|
|
||||||
|
Setelah login:
|
||||||
|
|
||||||
|
1. Ganti password admin seed.
|
||||||
|
2. Buat user production final.
|
||||||
|
3. Cek master data: currency, grade, bank.
|
||||||
|
4. Tes alur penting: purchase, receipt, lot, sales.
|
||||||
|
|
||||||
|
## 17. Update Deployment Berikutnya
|
||||||
|
|
||||||
|
Untuk server RAM rendah, tetap load env dan pakai swap sebelum build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u abelbirdnest -H bash
|
||||||
|
cd /var/www/abelbirdnest-web
|
||||||
|
git pull origin main
|
||||||
|
set -a
|
||||||
|
source .env.production
|
||||||
|
set +a
|
||||||
|
npm install
|
||||||
|
npm run prisma:generate
|
||||||
|
npm run prisma:migrate:deploy
|
||||||
|
NODE_OPTIONS=--max-old-space-size=1024 npm run build
|
||||||
|
exit
|
||||||
|
|
||||||
|
sudo systemctl restart abelbirdnest-web
|
||||||
|
curl https://abelbirdnest.id/api/v1/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## 18. Log dan Troubleshooting
|
||||||
|
|
||||||
|
Lihat log service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u abelbirdnest-web -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Status:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl status abelbirdnest-web
|
||||||
|
```
|
||||||
|
|
||||||
|
Restart:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart abelbirdnest-web
|
||||||
|
```
|
||||||
|
|
||||||
|
Cek OOM:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dmesg -T | tail -80
|
||||||
|
```
|
||||||
|
|
||||||
|
## 19. Backup Database
|
||||||
|
|
||||||
|
Backup manual:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u postgres pg_dump abelbirdnest_prod > /root/abelbirdnest_prod_$(date +%F_%H%M).sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Restore:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u postgres psql abelbirdnest_prod < /root/NAMA_FILE_BACKUP.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
## 20. Checklist Go-Live
|
||||||
|
|
||||||
|
- DNS `abelbirdnest.id` benar.
|
||||||
|
- DNS `www.abelbirdnest.id` benar.
|
||||||
|
- SSH port `3853` bisa login.
|
||||||
|
- Firewall buka `3853`, `80`, dan `443`.
|
||||||
|
- Swap aktif dan permanen.
|
||||||
|
- PostgreSQL jalan.
|
||||||
|
- `.env.production` ada dan permission `600`.
|
||||||
|
- Migration sukses.
|
||||||
|
- Seed currency, grade, dan bank sukses.
|
||||||
|
- Seed admin sukses.
|
||||||
|
- Build sukses dengan `NODE_OPTIONS=--max-old-space-size=1024`.
|
||||||
|
- systemd enabled dan running.
|
||||||
|
- Nginx proxy jalan.
|
||||||
|
- SSL aktif.
|
||||||
|
- `https://abelbirdnest.id/api/v1/health` ok.
|
||||||
|
- Admin bisa login.
|
||||||
|
- Password default sudah diganti.
|
||||||
|
- Backup database siap.
|
||||||
@ -9,6 +9,12 @@ Dokumen ini menyiapkan deploy production untuk:
|
|||||||
- source code dari git `https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git`
|
- source code dari git `https://git.iptek.co/wirabasalamah/AbelBirdNest-Stock.git`
|
||||||
- user service khusus `abelbirdnest`
|
- user service khusus `abelbirdnest`
|
||||||
|
|
||||||
|
Untuk server Debian 13 kosong dengan RAM rendah, SSH port `3853`, swap, seed admin, dan langkah lengkap yang sudah terbukti berhasil, lihat juga:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docs/deploy-debian13-low-ram.md
|
||||||
|
```
|
||||||
|
|
||||||
## 1. Persiapan Server
|
## 1. Persiapan Server
|
||||||
|
|
||||||
Siapkan:
|
Siapkan:
|
||||||
|
|||||||
Reference in New Issue
Block a user