> ## Documentation Index
> Fetch the complete documentation index at: https://qodex.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker Compose

> Run Qodex and Postgres together on one host with Docker Compose, with optional Redis and S3-compatible storage.

# 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](/self-hosted-aws-terraform).

## 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`

```yaml theme={null}
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.

```bash theme={null}
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

```bash theme={null}
docker compose up -d
```

Then watch Qodex boot:

```bash theme={null}
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:

```yaml theme={null}
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redisdata:/data
```

Then set:

```yaml theme={null}
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.

```yaml theme={null}
  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:

```yaml theme={null}
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

<CardGroup cols={2}>
  <Card title="Environment variables" icon="settings" href="/self-hosted-environment-variables">
    See the full configuration reference.
  </Card>

  <Card title="Storage backends" icon="hard-drive" href="/self-hosted-storage-backends">
    Choose local disk, S3, or MinIO.
  </Card>

  <Card title="Secret management" icon="key" href="/self-hosted-secret-management">
    Understand `QODECLAW_SECRET_KEY` before production.
  </Card>

  <Card title="AWS Terraform reference" icon="cloud" href="/self-hosted-aws-terraform">
    Move from one host to managed AWS infrastructure.
  </Card>
</CardGroup>
