Skip to main content
Docker Compose is the recommended way to run Draft Thinker locally or in a self-hosted environment. A single docker compose up command starts all five services: the gateway, Redis, Qdrant, Prometheus, and Grafana.

Services

ServiceImagePort(s)Purpose
gatewaybuilt from source8080API gateway
redisredis:7-alpine6379Short-term cache (key/value)
qdrantqdrant/qdrant:v1.14.16333, 6334Vector store for semantic cache
prometheusprom/prometheus:v3.2.19090Metrics collection
grafanagrafana/grafana:11.5.23000Metrics dashboards

docker-compose.yml

services:
  gateway:
    build: .
    ports:
      - "8080:8080"
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - REDIS_URL=redis:6379
      - QDRANT_URL=http://qdrant:6333
    volumes:
      - ./config.yaml:/etc/draft-thinker/config.yaml:ro
    depends_on:
      - redis
      - qdrant

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru

  qdrant:
    image: qdrant/qdrant:v1.14.1
    ports:
      - "6333:6333"
      - "6334:6334"
    volumes:
      - qdrant_data:/qdrant/storage

  prometheus:
    image: prom/prometheus:v3.2.1
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro

  grafana:
    image: grafana/grafana:11.5.2
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
      - ./grafana/dashboards:/var/lib/grafana/dashboards:ro
    depends_on:
      - prometheus

volumes:
  qdrant_data:

Volume mounts

gateway
  • ./config.yaml:/etc/draft-thinker/config.yaml:ro — mounts your local config.yaml into the container at the path the gateway reads on startup. Pass a different file by editing this mount; see custom config below.
prometheus
  • ./prometheus.yml:/etc/prometheus/prometheus.yml:ro — Prometheus scrape configuration. By default this scrapes the gateway at gateway:8080/metrics every 15 seconds.
grafana
  • ./grafana/provisioning:/etc/grafana/provisioning:ro — datasource and dashboard provisioning files.
  • ./grafana/dashboards:/var/lib/grafana/dashboards:ro — pre-built dashboard JSON files.
qdrant
  • qdrant_data (named volume) — persists vector store data across container restarts. The volume is declared at the bottom of the Compose file and managed by Docker.

Redis memory settings

Redis is started with two flags:
  • --maxmemory 256mb — caps memory usage at 256 MB.
  • --maxmemory-policy allkeys-lru — evicts the least-recently-used keys when the limit is reached, keeping the cache from growing unbounded.

Deployment workflow

1

Set your OpenAI API key

Export OPENAI_API_KEY in your shell before running Compose. Docker Compose reads it from the environment and passes it to the gateway container.
export OPENAI_API_KEY=sk-...
Keep OPENAI_API_KEY as a shell environment variable rather than hardcoding it in docker-compose.yml. Docker Compose substitutes ${OPENAI_API_KEY} at runtime, so the key never lands in source control.
2

Start all services

From the repository root:
docker compose up -d
Docker builds the gateway image from the local Dockerfile, pulls the other images, and starts all five containers in the background.
3

Verify the gateway is running

curl http://localhost:8080/metrics
A response with Prometheus metric lines confirms the gateway started successfully.
4

Open Grafana (optional)

Navigate to http://localhost:3000 and log in with the default credentials (admin / admin). Pre-provisioned dashboards are available immediately.

Common operations

View logs for a specific service:
docker compose logs -f gateway
Stop all services:
docker compose down
This stops and removes the containers but preserves the qdrant_data volume. To also delete the volume:
docker compose down -v
Rebuild the gateway after a code change:
docker compose up -d --build gateway
This rebuilds only the gateway image and restarts that container, leaving Redis, Qdrant, Prometheus, and Grafana untouched.

Custom config

The gateway loads its configuration from the file mounted at /etc/draft-thinker/config.yaml. The Compose file mounts ./config.yaml from the repository root by default:
volumes:
  - ./config.yaml:/etc/draft-thinker/config.yaml:ro
To use a different file, update the left-hand side of the mount:
volumes:
  - ./my-custom-config.yaml:/etc/draft-thinker/config.yaml:ro
You can also override the config path entirely using the --config flag in the gateway’s CMD. For example, to point to a different path inside the container:
command: ["--config", "/run/secrets/draft-thinker-config.yaml"]

Build docs developers (and LLMs) love