Initial commit
This commit is contained in:
337
cpone-dashboard/DEPLOY.md
Normal file
337
cpone-dashboard/DEPLOY.md
Normal file
@@ -0,0 +1,337 @@
|
||||
# Deployment Guide — cpone-dashboard
|
||||
|
||||
Dokumen ini mencatat semua yang dilakukan dari awal sampai app berjalan di server, lengkap dengan langkah untuk deploy ulang atau deploy ke server baru.
|
||||
|
||||
---
|
||||
|
||||
## Ringkasan Yang Dikerjakan
|
||||
|
||||
### Fitur yang diimplementasi
|
||||
|
||||
| Fitur | File |
|
||||
|-------|------|
|
||||
| Result menu — list pasien + View PDF modal | `menu/result/query.go`, `menu/result/handler.go`, `templates/result/index.html` |
|
||||
| PDF base URL via env | `config/config.go`, `.env`, `main.go` |
|
||||
| BASE_PATH — akses via sub-path tanpa port | `config/config.go`, semua handler, semua template |
|
||||
| Login path `/mcu-login` (hindari konflik Apache) | `menu/auth/route.go`, `menu/auth/handler.go`, `menu/auth/middleware.go`, `templates/login/index.html` |
|
||||
| Demo data seed (1500 pasien MCU DEMO 2026) | `scripts/demo_seed.py` |
|
||||
| Live simulation script | `scripts/demo_live.sh` |
|
||||
| Deploy ke devcpone via systemd user service | `Makefile`, `.config/systemd/user/cpone-dashboard.service` |
|
||||
|
||||
### Perubahan kode
|
||||
|
||||
```
|
||||
config/config.go → tambah PDFBaseURL + BasePath field
|
||||
.env / .env.example → tambah PDF_BASE_URL + BASE_PATH
|
||||
main.go → b() template func, mount routes kondisional,
|
||||
SetBasePath ke semua package
|
||||
menu/auth/route.go → /login → /mcu-login
|
||||
menu/auth/handler.go → SetBasePath, redirect pakai basePath
|
||||
menu/auth/middleware.go → redirect ke basePath+/mcu-login
|
||||
menu/result/query.go → full implementation (ResultRow, GetResultRows, filter)
|
||||
menu/result/handler.go → full implementation (pageData, Index, SetPDFBaseURL, SetBasePath)
|
||||
menu/dashboard/handler.go → SetBasePath, redirect pakai basePath
|
||||
menu/arrival/handler.go → SetBasePath, redirect pakai basePath
|
||||
menu/progress/handler.go → SetBasePath, redirect pakai basePath
|
||||
menu/abnormal/handler.go → SetBasePath, redirect pakai basePath
|
||||
menu/projects/handler.go → SetBasePath, redirect pakai basePath
|
||||
templates/layout/base.html → semua nav link pakai {{b "/..."}}
|
||||
templates/login/index.html → src + action pakai {{b "/..."}}
|
||||
templates/auth/password.html → semua link pakai {{b "/..."}}
|
||||
templates/projects/index.html → semua link pakai {{b "/..."}}
|
||||
templates/dashboard/index.html → sse-connect, form action, fetch() pakai {{b "/..."}}
|
||||
templates/arrival/index.html → link + form action pakai {{b "/..."}}
|
||||
templates/progress/index.html → link + form action pakai {{b "/..."}}
|
||||
templates/abnormal/index.html → tab links pakai {{b "/..."}}
|
||||
templates/result/index.html → full template (4 section + PDF modal dialog)
|
||||
scripts/demo_seed.py → generate 1500 pasien demo + kelainan + published
|
||||
scripts/demo_live.sh → simulasi live MCU (checkin, station, validasi, publish)
|
||||
scripts/demo_cleanup.sql → hapus semua data demo
|
||||
scripts/README.md → panduan penggunaan demo scripts
|
||||
Makefile → update deploy target (systemd), tambah logs + status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Arsitektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ devcpone server │
|
||||
│ │
|
||||
│ cpone-dashboard (Go binary, port 8090) │
|
||||
│ │ │
|
||||
│ └── MySQL 3306 → cpone_dashboard (DB utama) │
|
||||
│ ├── mcu_project │
|
||||
│ ├── mcu_patient │
|
||||
│ ├── mcu_checkinout │
|
||||
│ ├── mcu_station_progress │
|
||||
│ ├── mcu_patient_resume_status │
|
||||
│ ├── published_mcu_dashboard_sync │
|
||||
│ ├── kelainan_details │
|
||||
│ └── ... (lihat db/migrations/) │
|
||||
│ │
|
||||
│ /home/one/project/one/dashboard-files/ ← file PDF │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
|
||||
Di laptop (dev):
|
||||
DB diakses via SSH tunnel → localhost:3307 → devcpone:3306
|
||||
make start (buka tunnel + jalankan app lokal)
|
||||
```
|
||||
|
||||
**Tech stack:** Go 1.21, Chi router, HTML templates (embed), HTMX, Tailwind CDN, ECharts CDN, MySQL 8
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Di laptop (build)
|
||||
- Go 1.21+ (`/usr/local/go/bin/go`)
|
||||
- SSH access ke `one@devcpone.aplikasi.web.id`
|
||||
- Python 3 (untuk generate demo data)
|
||||
|
||||
### Di server tujuan
|
||||
- Ubuntu/Linux x86_64
|
||||
- MySQL 8 dengan database `cpone_dashboard` sudah ada dan migration sudah dijalankan
|
||||
- Systemd user service tersedia (`systemctl --user`)
|
||||
- User dengan akses ke MySQL (`admin:password@127.0.0.1:3306`)
|
||||
- Direktori untuk file PDF: `/path/to/dashboard-files/` bisa diakses via HTTP
|
||||
|
||||
---
|
||||
|
||||
## Deploy Pertama Kali (Server Baru)
|
||||
|
||||
### 1. Persiapan database
|
||||
|
||||
Pastikan database `cpone_dashboard` sudah ada dan semua migration dijalankan:
|
||||
|
||||
```bash
|
||||
ssh user@server "mysql -u admin -pPASSWORD -e 'SHOW DATABASES;'"
|
||||
```
|
||||
|
||||
Jalankan migration satu per satu jika belum:
|
||||
|
||||
```bash
|
||||
ssh user@server "mysql -u admin -pPASSWORD cpone_dashboard < /path/migration/001_init_schema.sql"
|
||||
# dst untuk 002 - 011
|
||||
```
|
||||
|
||||
Migration ada di: `db/migrations/001_init_schema.sql` sampai `011_patient_resume_status.sql`
|
||||
|
||||
### 2. Buat direktori deploy di server
|
||||
|
||||
```bash
|
||||
ssh user@server "mkdir -p /home/user/project/cpone-dashboard"
|
||||
```
|
||||
|
||||
### 3. Buat file .env di server
|
||||
|
||||
```bash
|
||||
ssh user@server "cat > /home/user/project/cpone-dashboard/.env << 'EOF'
|
||||
APP_PORT=8090
|
||||
DB_DSN=admin:PASSWORD@tcp(127.0.0.1:3306)/cpone_dashboard?parseTime=true&loc=Local
|
||||
AUTH_SECRET=ganti-dengan-string-random-32-karakter
|
||||
PDF_BASE_URL=http://domain-server/dashboard-files/
|
||||
EOF"
|
||||
```
|
||||
|
||||
Sesuaikan:
|
||||
- `APP_PORT` — port yang belum dipakai di server (cek dengan `ss -tlnp`)
|
||||
- `DB_DSN` — sesuaikan host, port, user, password, nama database
|
||||
- `AUTH_SECRET` — string random minimal 32 karakter, bisa generate: `openssl rand -hex 32`
|
||||
- `PDF_BASE_URL` — URL publik ke folder tempat file PDF disimpan
|
||||
|
||||
### 4. Buat systemd user service
|
||||
|
||||
```bash
|
||||
ssh user@server "mkdir -p ~/.config/systemd/user && cat > ~/.config/systemd/user/cpone-dashboard.service << 'EOF'
|
||||
[Unit]
|
||||
Description=CpOne Dashboard
|
||||
ConditionPathExists=/home/user/project/cpone-dashboard/cpone-dashboard
|
||||
After=network.target
|
||||
StartLimitIntervalSec=60
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
WorkingDirectory=/home/user/project/cpone-dashboard
|
||||
ExecStart=/home/user/project/cpone-dashboard/cpone-dashboard
|
||||
EnvironmentFile=/home/user/project/cpone-dashboard/.env
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF"
|
||||
```
|
||||
|
||||
Ganti `/home/user` dengan home directory user yang dipakai.
|
||||
|
||||
### 5. Update Makefile untuk server baru
|
||||
|
||||
Edit bagian atas `Makefile`:
|
||||
|
||||
```makefile
|
||||
SERVER=user@server-baru.domain.com
|
||||
DEPLOY_DIR=/home/user/project/cpone-dashboard
|
||||
```
|
||||
|
||||
### 6. Build dan deploy
|
||||
|
||||
```bash
|
||||
cd /path/to/cpone-dashboard
|
||||
make deploy
|
||||
```
|
||||
|
||||
Perintah ini:
|
||||
1. Cross-compile binary untuk linux/amd64
|
||||
2. Upload ke server via SCP
|
||||
3. Restart systemd service
|
||||
|
||||
### 7. Enable service agar auto-start saat reboot
|
||||
|
||||
```bash
|
||||
ssh user@server "systemctl --user enable cpone-dashboard"
|
||||
```
|
||||
|
||||
### 8. Verifikasi
|
||||
|
||||
```bash
|
||||
make status # cek status service
|
||||
make logs # lihat log live
|
||||
|
||||
# Atau langsung dari browser:
|
||||
# http://server-domain:PORT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deploy Ulang (Update Kode)
|
||||
|
||||
Cukup jalankan:
|
||||
|
||||
```bash
|
||||
cd /Users/fajrihardhitamurti/REPO_CPONE_DASHBOARD/cpone-dashboard
|
||||
make deploy
|
||||
```
|
||||
|
||||
Itu saja. Build → upload → restart otomatis.
|
||||
|
||||
---
|
||||
|
||||
## Development Lokal
|
||||
|
||||
```bash
|
||||
cd /Users/fajrihardhitamurti/REPO_CPONE_DASHBOARD/cpone-dashboard
|
||||
|
||||
# Jalankan (buka SSH tunnel ke devcpone:3306 → localhost:3307, lalu start app)
|
||||
make start
|
||||
|
||||
# Stop (tutup tunnel + kill app)
|
||||
make stop
|
||||
|
||||
# Akses di browser: http://localhost:8080
|
||||
```
|
||||
|
||||
File `.env` lokal menggunakan:
|
||||
```
|
||||
DB_DSN=...@tcp(127.0.0.1:3307)/cpone_dashboard... ← via tunnel port 3307
|
||||
APP_PORT=8080
|
||||
PDF_BASE_URL=http://devcpone.aplikasi.web.id/dashboard-files/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Konfigurasi .env
|
||||
|
||||
| Key | Keterangan | Contoh |
|
||||
|-----|-----------|--------|
|
||||
| `APP_PORT` | Port HTTP server | `8090` |
|
||||
| `DB_DSN` | MySQL DSN (Go format) | `user:pass@tcp(host:3306)/dbname?parseTime=true&loc=Local` |
|
||||
| `AUTH_SECRET` | Secret untuk session cookie JWT | string random 32+ karakter |
|
||||
| `PDF_BASE_URL` | Base URL untuk file PDF resume individu | `http://domain/dashboard-files/` |
|
||||
|
||||
`PDF_BASE_URL` harus diakhiri `/`. File PDF disimpan di server dengan path relatif misal `2026/04/R2604xxxx_resume_individu.pdf`, sehingga full URL = `PDF_BASE_URL + relative_path`.
|
||||
|
||||
---
|
||||
|
||||
## Struktur File di Server
|
||||
|
||||
```
|
||||
/home/one/project/cpone-dashboard/
|
||||
├── cpone-dashboard ← binary (hasil build)
|
||||
└── .env ← konfigurasi (jangan commit ke git)
|
||||
|
||||
/home/one/.config/systemd/user/
|
||||
└── cpone-dashboard.service ← systemd unit file
|
||||
|
||||
/home/one/project/one/dashboard-files/
|
||||
└── 2026/
|
||||
└── 04/
|
||||
└── R2604xxxx_resume_individu.pdf ← file PDF hasil MCU
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Service gagal start:**
|
||||
```bash
|
||||
journalctl --user -u cpone-dashboard -n 30 --no-pager
|
||||
```
|
||||
|
||||
**Port sudah dipakai:**
|
||||
```bash
|
||||
ss -tlnp | grep PORT
|
||||
# Ganti APP_PORT di .env, lalu restart
|
||||
systemctl --user restart cpone-dashboard
|
||||
```
|
||||
|
||||
**Terlalu banyak restart (failed state):**
|
||||
```bash
|
||||
systemctl --user stop cpone-dashboard
|
||||
systemctl --user reset-failed cpone-dashboard
|
||||
systemctl --user start cpone-dashboard
|
||||
```
|
||||
|
||||
**Database tidak bisa connect:**
|
||||
- Pastikan `DB_DSN` di `.env` benar
|
||||
- Cek MySQL berjalan: `mysql -u admin -pPASS -e "SELECT 1;"`
|
||||
- Kalau pakai tunnel (dev lokal): pastikan tunnel aktif
|
||||
|
||||
**Binary tidak update:**
|
||||
```bash
|
||||
# Cek binary sudah ter-upload
|
||||
ssh one@devcpone.aplikasi.web.id "ls -lh /home/one/project/cpone-dashboard/cpone-dashboard"
|
||||
# Force build ulang
|
||||
cd /path/to/repo && make deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Demo Data (Opsional)
|
||||
|
||||
Untuk demo ke client dengan data realistis (MCU PROJECT DEMO 2026, 1500 pasien):
|
||||
|
||||
```bash
|
||||
# Seed data
|
||||
python3 scripts/demo_seed.py | ssh one@devcpone.aplikasi.web.id \
|
||||
"mysql -u admin -pSasone\!102938 cpone_dashboard"
|
||||
|
||||
# Buat PDF demo di server
|
||||
ssh one@devcpone.aplikasi.web.id "
|
||||
mkdir -p /home/one/project/one/dashboard-files/2026/04
|
||||
SRC=/home/one/project/one/dashboard-files/2024/09/R2409170003_resume_individu.pdf
|
||||
for i in \$(seq 1 80); do
|
||||
cp \"\$SRC\" \"/home/one/project/one/dashboard-files/2026/04/R2604\$(printf '%04d' \$i)_resume_individu.pdf\"
|
||||
done
|
||||
"
|
||||
|
||||
# Upload live script
|
||||
scp scripts/demo_live.sh one@devcpone.aplikasi.web.id:/home/one/demo_live.sh
|
||||
ssh one@devcpone.aplikasi.web.id "chmod +x /home/one/demo_live.sh"
|
||||
|
||||
# Jalankan simulasi live saat demo
|
||||
ssh one@devcpone.aplikasi.web.id "/home/one/demo_live.sh 5"
|
||||
```
|
||||
|
||||
Detail lengkap lihat `scripts/README.md`.
|
||||
Reference in New Issue
Block a user