Security fixes: P0-P2 complete (22 fixes)
P0 (7): Auth-bypass removed, migrations fixed, plugin-upload disabled, RLS FORCE+WITH CHECK, plugin double-registration fixed, persistent volume, domain removed P1 (11): User/tenant model, Redis centralized, worker separated, transactional outbox, XSS fixed, DMS chunked streaming, permissions unified, password reset, metrics secured, config/docs fixed, cross-tenant FK P2 (4): Contact model normalized, cross-imports reduced 94%, commands+state machines for contacts/dms/mail/calendar, SPA path-traversal 8 new migrations, 99 unit tests, 13 commands, 8 contracts, 72 files changed
This commit is contained in:
+54
-3
@@ -3,13 +3,15 @@
|
||||
Production deployment guide for the **CRM System** to the Coolify PaaS instance
|
||||
at `server.media-on.de` (server UUID `lw80w8scs4044gwcw084s00s4`).
|
||||
|
||||
The deploy consists of **two Coolify resources** in the same project/environment:
|
||||
The deploy consists of **three Coolify resources** in the same project/environment:
|
||||
|
||||
1. A **PostgreSQL 16** database resource (one-click or Docker image).
|
||||
2. The **crm-app** Application (Dockerfile build from a Git repository).
|
||||
3. The **crm-worker** Application (same Dockerfile build, different entrypoint).
|
||||
|
||||
The two resources talk to each other over the internal Docker network. The app
|
||||
The resources talk to each other over the internal Docker network. The app
|
||||
is exposed publicly on `https://crm.media-on.de:443` (Let's Encrypt via Coolify).
|
||||
The worker is not exposed publicly — it only needs Redis and PostgreSQL access.
|
||||
|
||||
---
|
||||
|
||||
@@ -174,7 +176,7 @@ In **crm-app → Domains → + Add Domain**:
|
||||
|
||||
In **crm-app → Advanced → Healthcheck**:
|
||||
|
||||
- **Healthcheck path**: `/health`
|
||||
- **Healthcheck path**: `/api/v1/health`
|
||||
- **Healthcheck method**: `GET`
|
||||
- **Healthcheck interval**: `30s`
|
||||
- **Healthcheck timeout**: `10s`
|
||||
@@ -267,3 +269,52 @@ For full incident response, see [`/a0/.a0/runbook-restore.md`](../../a0/runbook-
|
||||
- App architecture (Section 13 lockdown) — `/a0/.a0/02-architecture.md`
|
||||
- Task graph (Phase 4d) — `/a0/.a0/03-task-graph.json`
|
||||
- Restore runbook — `/a0/.a0/runbook-restore.md`
|
||||
|
||||
---
|
||||
|
||||
## 11. Resource C — crm-worker (Background Worker)
|
||||
|
||||
The crm-worker runs the ARQ background worker and scheduler in a separate
|
||||
container, using the same Docker image as crm-app but with a different
|
||||
entrypoint (`/app/worker.sh` instead of `/app/prestart.sh`).
|
||||
|
||||
### Setup in Coolify UI
|
||||
|
||||
1. In the same project/environment as crm-app, **+ Add → Application →
|
||||
Public/Private Repository**.
|
||||
2. Fill in:
|
||||
- **Git repository**: same as crm-app (`https://forgejo.media-on.de/Leopoldadmin/leocrm.git`)
|
||||
- **Branch**: `main`
|
||||
- **Build pack**: `Dockerfile`
|
||||
- **Dockerfile location**: `Dockerfile` (same image)
|
||||
- **Port**: `8000` (not used, but Coolify requires a port)
|
||||
- **Custom Entrypoint**: `/app/worker.sh`
|
||||
3. Click **Deploy** once to create the resource.
|
||||
4. Note the **Application UUID**.
|
||||
|
||||
### Environment variables (on the crm-worker resource)
|
||||
|
||||
Set the same variables as crm-app, except:
|
||||
|
||||
| Key | Value | Notes |
|
||||
|-----|-------|-------|
|
||||
| `DATABASE_URL` | same as crm-app | |
|
||||
| `REDIS_URL` | same as crm-app | |
|
||||
| `SECRET_KEY` | same as crm-app | |
|
||||
| `ENVIRONMENT` | `production` | |
|
||||
| `LOG_LEVEL` | `INFO` | |
|
||||
| `STORAGE_PATH` | `/data/storage` | |
|
||||
|
||||
No domain is needed — the worker is not publicly accessible.
|
||||
|
||||
### Healthcheck (Coolify side)
|
||||
|
||||
- **Healthcheck path**: `/api/v1/health` (not used by worker, but Coolify requires one)
|
||||
- Alternatively, use a custom healthcheck command:
|
||||
`pgrep -f "arq app.core.worker.WorkerSettings" || exit 1`
|
||||
|
||||
### Scaling
|
||||
|
||||
To scale the worker horizontally, deploy multiple crm-worker instances.
|
||||
Cron jobs use a Redis-based distributed lock (`SET NX` with TTL) so only
|
||||
one replica executes each scheduled job.
|
||||
|
||||
Reference in New Issue
Block a user