Skip to main content

Docker Compose

Use Docker Compose when you want a self-hosted Qodex stack on one machine. Compose is a good fit for internal staging, small deployments, on-premise trials, and teams that want Postgres included in the same stack. For production with managed AWS services, use the AWS Terraform reference.

What this stack includes

  • Qodex web app and agent container.
  • Postgres 17 for product state.
  • A persistent Qodex data volume for artifacts.
  • Optional Redis for queue mode.
  • Optional MinIO for S3-compatible artifact storage.

Prerequisites

  • Docker Engine 24+ with the Compose plugin.
  • At least 4 GB memory available to the Qodex container.
  • An OpenAI API key.
  • Random values for QODECLAW_SECRET_KEY and JWT_SECRET.

1. Create docker-compose.yml

services:
  qodex:
    image: ghcr.io/flinket/qodeclaw:latest
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
      PORT: "3000"
      DATABASE_URL: postgres://qodeclaw:qodeclaw@postgres:5432/qodeclaw
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      QODECLAW_SECRET_KEY: ${QODECLAW_SECRET_KEY}
      JWT_SECRET: ${JWT_SECRET}
      APP_URL: ${APP_URL:-http://localhost:3000}
      STORAGE_BACKEND: local
    volumes:
      - qodex-data:/data
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: qodeclaw
      POSTGRES_PASSWORD: qodeclaw
      POSTGRES_DB: qodeclaw
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U qodeclaw"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  pgdata:
  qodex-data:
The qodex-data volume stores artifacts such as screenshots, videos, DOM snapshots, logs, and attachments.

2. Add .env

Create a .env file next to the compose file.
OPENAI_API_KEY=sk-...
QODECLAW_SECRET_KEY=<32-or-more-char-random-string>
JWT_SECRET=<random-string>
APP_URL=http://localhost:3000
Keep this file out of version control.

3. Start the stack

docker compose up -d
Then watch Qodex boot:
docker compose logs -f qodex
The boot log shows which critical environment variables are present. It does not print secret values.

Add Redis when you need queue mode

Redis is optional. Without Redis, the scheduler and agent runner run in the Qodex container. With Redis, Qodex can run workers and scheduler processes separately. Add Redis when you need horizontal scaling or separate worker containers:
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redisdata:/data
Then set:
REDIS_URL: redis://redis:6379

Add MinIO for S3-compatible storage

Use MinIO if you want the local stack to behave more like production S3.
  minio:
    image: minio/minio:latest
    restart: unless-stopped
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio-secret-change-me
    volumes:
      - miniodata:/data
Then configure Qodex:
STORAGE_BACKEND: s3
S3_BUCKET: qodex-blobs
AWS_REGION: us-east-1
AWS_ACCESS_KEY_ID: minio
AWS_SECRET_ACCESS_KEY: minio-secret-change-me
AWS_ENDPOINT_URL: http://minio:9000
Create the bucket once from the MinIO console or client before running tests that write artifacts.

When Compose is enough

Compose is usually enough for:
  • A small internal self-hosted deployment.
  • A staging or proof-of-concept environment.
  • An on-premise install behind a corporate firewall.
  • A local environment that mirrors production behavior.
Use the AWS reference when you need managed Postgres backups, HTTPS termination, central logs, and a cleaner production scaling path.

Next steps

Environment variables

See the full configuration reference.

Storage backends

Choose local disk, S3, or MinIO.

Secret management

Understand QODECLAW_SECRET_KEY before production.

AWS Terraform reference

Move from one host to managed AWS infrastructure.