338 lines
11 KiB
Markdown
338 lines
11 KiB
Markdown
# 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`.
|