production docker deployment update

This commit is contained in:
Alberto-Audrix committed 2026-09-10 15:44:34 +07:00
1 parent 11b0ca26a5
commit ded52d1ece
12 files changed
+616

No files matched your search

+210
View File
@@ -0,0 +1,210 @@
# Docker Deployment Guide
Deploy **dashboard-cpsp-executive** (HQ) with Docker Compose. Same layout as site `dashboard-cpsp` (Postgres + API + Nginx frontend + cron), with HQ ports and city-edge syncs **off** by default.
## Architecture
```
┌──────────────────────────────────────────────────────────────┐
│ HQ Host Server │
│ │
│ ┌─────────────┐ /api/* ┌──────────────┐ │
│ │ frontend │────────────►│ api │ │
│ │ (Nginx) │ │ (Django) │ │
│ │ port 80 │ │ port 8000 │ │
│ └─────────────┘ └──────┬───────┘ │
│ │ │
│ ┌─────────────┐ ▼ │
│ │ cron │────────────► ┌──────────────┐ │
│ │ (same image)│ │ database │ │
│ └─────────────┘ │ (PostgreSQL) │ │
│ │ port 15433* │ │
│ └──────────────┘ │
└──────────────────────────────────────────────────────────────┘
* 15433 on host → 5432 in container (SSH tunnel / DBeaver)
Host API debug port: 18001 → 8000 (site app uses 18000 / 15432)
```
| Container | Image / build | Host port | Role |
| ---------- | ------------------ | ---------------- | ----------------------------- |
| frontend | `docker/Dockerfile.web` | 80 → 80 | React SPA + Nginx API proxy |
| api | `docker/Dockerfile.api` | 18001 → 8000 | Gunicorn, migrations, static |
| cron | same as api | — | KPI rollups (+ optional edge syncs) |
| database | postgres:16-alpine | 15433 → 5432 | PostgreSQL |
## Prerequisites
- Docker 20.10+
- Docker Compose v2+
- Ports available: **80** (UI), **18001** (direct API), **15433** (Postgres on localhost)
```bash
docker --version
docker compose version
```
## Quick start
```bash
cd dashboard-cpsp-executive
cp docker/.env.example .env
# Edit .env — set SECRET_KEY and DB_PASSWORD
docker compose up -d --build
```
API entrypoint runs `migrate` + `bootstrap_admin` on every start (needs `BOOTSTRAP_ADMIN_PASSWORD` in `.env`).
**Production** (empty database, no demo data): log in with the bootstrap admin, then create users/sites via the UI. Do **not** run `seed_demo` on production.
**Dev / demo** (sample data):
```bash
docker compose exec api python manage.py seed_demo
```
### Verify
```bash
docker compose ps
docker compose logs -f
curl http://localhost/health
curl http://localhost/api/v1/health/
```
Open **http://localhost** in a browser.
## Configuration files (`docker/`)
| File | Purpose |
| ---- | ------- |
| `Dockerfile.web` | Frontend image (Vite + Nginx) |
| `Dockerfile.api` | Backend image (Django + Gunicorn) |
| `nginx.conf` | Nginx proxy config for frontend |
| `entrypoint-api.sh` | API container startup |
| `entrypoint-cron.sh` | Cron container startup |
| `crontab` | Fallback schedule; runtime regenerated from `DASHBOARD_PUBLISH_*` |
| `.env.example` | Compose env template → copy to project root `.env` |
| `compose.override.local.example` | Optional local Postgres port override |
## Configuration
Compose reads variables from a root `.env` file. Template: `docker/.env.example`.
Important production values:
| Variable | Purpose |
| -------- | ------- |
| `SECRET_KEY` | Django secret — use a long random string |
| `DB_PASSWORD` | PostgreSQL password |
| `CSRF_TRUSTED_ORIGINS` | Must include your public UI origin (e.g. `https://executive.example.com`) |
| `CORS_ALLOWED_ORIGINS` | Same as above if the SPA is on a different origin |
| `BOOTSTRAP_ADMIN_USER` | Superuser username for `bootstrap_admin` (default `admin`) |
| `BOOTSTRAP_ADMIN_PASSWORD` | Superuser password (required) |
| `BOOTSTRAP_STAFF_USER` | Optional GM username; leave empty to skip |
| `BOOTSTRAP_STAFF_PASSWORD` | GM password (required when `BOOTSTRAP_STAFF_USER` is set) |
| `BOOTSTRAP_API_KEY` | Optional fixed API key for city inbound / scripts (hashed at rest) |
City-edge sync flags default to **false** at HQ. Enable only if this host also pulls directly from IoT / karung / chicken-counting edge APIs.
## Management
```bash
# Start / stop
docker compose start
docker compose stop
docker compose restart
# Logs
docker compose logs -f api
docker compose logs -f frontend
docker compose logs -f cron
# Django shell
docker compose exec api python manage.py shell
# Database (psql)
docker compose exec database psql -U executive -d executive
# From host (port 15433)
psql -h localhost -p 15433 -U executive -d executive
```
### Update after code changes
```bash
git pull
docker compose down
docker compose up -d --build
```
Rolling update (less downtime):
```bash
docker compose build
docker compose up -d --no-deps --build api
docker compose up -d --no-deps --build cron
docker compose up -d --no-deps --build frontend
```
### Local DBeaver on Mac
```bash
cp docker/compose.override.local.example docker-compose.override.yml
```
Adds `127.0.0.1:5432:5432` while keeping the server’s `15433` mapping.
## Cron jobs
The `cron` service runs:
- **Every 10 min** — `sync_iot_from_api` / `sync_chicken_counting_from_edge` (no-op while sync flags are false)
- **At `DASHBOARD_PUBLISH_HOUR`:`DASHBOARD_PUBLISH_MINUTE` daily** — optional karung sync then `recompute_kpi_rollups`
Karung 30s loop starts only when `KARUNG_WEB_ADMIN_SYNC_ENABLED=true`.
Logs: `docker compose exec cron tail -f /var/log/cron.log`
## Troubleshooting
**API unhealthy**
```bash
docker compose logs api
docker compose exec api python manage.py migrate --plan
```
**Frontend 502 on /api**
```bash
docker compose ps
curl http://127.0.0.1:18001/api/v1/health/
```
**Database connection errors**
Check Postgres is healthy and credentials in `.env` match `docker-compose.yml` defaults.
**Port conflicts**
Change mappings in `docker-compose.yml`, e.g. `"8080:80"` for frontend. Site app already uses 80 / 18000 / 15432 on city hosts.
**Reset database** (destructive)
```bash
docker compose down -v
docker compose up -d --build
```
## Security notes
- Do not commit `.env` with real secrets.
- Use strong `SECRET_KEY` and `DB_PASSWORD` in production.
- Restrict database port `15433` to localhost (already bound to `127.0.0.1`).
- Put HTTPS in front of port 80 (reverse proxy + Let's Encrypt) for public deployment.
---
Docker deployment guide — dashboard-cpsp-executive