Run a separate worker
DOCX and PDF exports and Mermaid diagram renders run in headless Chromium. By default (APP_ROLE=all), one
container serves HTTP and runs these jobs. A large export then competes with request handling for CPU and
memory.
To keep them apart, run the same image twice with different roles:
| Container | APP_ROLE | Does |
|---|---|---|
app | api | Serves the web app, the API and assistant streams. Publishes the port. |
worker | worker | Runs export and diagram render jobs. Serves no HTTP and publishes no port. |
Jobs travel through Postgres (pg-boss), so the two containers need nothing besides the same database. Both
need the same DATABASE_URL, MASTER_KEY and PUBLIC_URL, because every role validates the full
configuration at startup.
Compose file
Add APP_ROLE: api to the app service and a worker service next to it:
app:
image: iqbalr3000/jangka:${JANGKA_VERSION:-latest}
container_name: jangka
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: postgres://jangka:jangka@postgres:5432/jangka
MASTER_KEY: ${MASTER_KEY:?set MASTER_KEY (openssl rand -base64 32)}
PUBLIC_URL: ${PUBLIC_URL:-http://localhost:3000}
APP_ROLE: api
ports:
- "3000:3000"
worker:
image: iqbalr3000/jangka:${JANGKA_VERSION:-latest}
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: postgres://jangka:jangka@postgres:5432/jangka
MASTER_KEY: ${MASTER_KEY:?set MASTER_KEY (openssl rand -base64 32)}
PUBLIC_URL: ${PUBLIC_URL:-http://localhost:3000}
APP_ROLE: workerdocker compose up -d
docker compose logs -f workerBoth containers run database migrations on start. They take a lock first, so starting them together is safe.
Keep them on one version
Both services use the same image tag. When you upgrade, change it in both places. An API and a worker on different versions may disagree on the database schema. See Upgrading.
Health
The image's health check calls /api/v1/health for the api and all roles. A worker container serves no
HTTP, so its health check only reports that the process is running. Check docker compose logs worker to see
whether jobs succeed.