jngkadocs
Operations / Run a separate worker

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:

ContainerAPP_ROLEDoes
appapiServes the web app, the API and assistant streams. Publishes the port.
workerworkerRuns 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:

docker-compose.ymlyaml
  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: worker
terminalsh
docker compose up -d
docker compose logs -f worker

Both 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.