Skip to main content

Docker Compose Deployment

This guide walks through deploying Octokraft using Docker Compose. This is the recommended approach for small teams (under 50 developers) or evaluation environments.

Prerequisites

  • Linux server (Ubuntu 22.04+ recommended)
  • Docker 24.x+ with Docker Compose v2
  • A registered GitHub App (see GitHub Integration)
  • A Clerk account for authentication
  • Access to an OpenAI-compatible AI model API

Quick Start

1

Get deployment files

Download the Octokraft deployment package, which includes docker-compose.yml, .env.example, and supporting configuration files.
2

Configure environment

Copy the example environment file and fill in your values:
cp .env.example .env
Edit .env and set all required variables. See the environment variables section below for the full list.
3

Start services

docker compose up -d
This starts Octokraft along with bundled infrastructure services (PostgreSQL, Redis, FalkorDB, Temporal). If you are using external managed services, remove the corresponding entries from docker-compose.yml and update the connection strings in your .env file.
4

Run database migrations

docker compose exec api octokraft migrate up
5

Verify the deployment

curl http://localhost:8080/healthz
A successful response confirms the API server is running and connected to all infrastructure services.

Environment Variables

These are the key variables you must configure. For the complete list, see the Configuration Reference.

Required

VariableDescription
DATABASE_URLPostgreSQL connection string (e.g., postgres://user:pass@host:5432/octokraft?sslmode=disable)
REDIS_URLRedis connection string (e.g., redis://host:6379)
TEMPORAL_ADDRESSTemporal server address (e.g., temporal:7233)
FALKORDB_HOSTFalkorDB host address (e.g., falkordb:6379)
SECRET_KEYEncryption key for API tokens. Generate with openssl rand -hex 32.
CLERK_SECRET_KEYYour Clerk API secret key
CLERK_JWT_ISSUERYour Clerk JWT issuer URL
GITHUB_APP_IDYour GitHub App ID
GITHUB_PRIVATE_KEY_PATHPath to your GitHub App private key .pem file
GITHUB_WEBHOOK_SECRETSecret used to verify GitHub webhook payloads
CORS_ORIGINSAllowed CORS origins (e.g., https://octokraft.yourcompany.com)
FRONTEND_URLPublic URL of the frontend (e.g., https://octokraft.yourcompany.com)

AI Model Configuration

At minimum, configure the OpenAI large model slot. See Configuration Reference for all 4 slots.
VariableDescription
LLM_OPENAI_LARGE_PROVIDERProvider name (e.g., openai, azure, openrouter)
LLM_OPENAI_LARGE_MODELModel identifier (e.g., gpt-4o)
LLM_OPENAI_LARGE_API_KEYAPI key for the provider
LLM_OPENAI_LARGE_BASE_URLAPI endpoint URL
LLM_OPENAI_SMALL_PROVIDERProvider for the small model slot
LLM_OPENAI_SMALL_MODELModel identifier (e.g., gpt-4o-mini)
LLM_OPENAI_SMALL_API_KEYAPI key
LLM_OPENAI_SMALL_BASE_URLAPI endpoint URL

Docker Compose File

Below is a reference docker-compose.yml with all services. Adjust as needed — if you use managed PostgreSQL or Redis, remove those services and update connection strings.
services:
  # Octokraft application
  api:
    image: ghcr.io/octokraft/octokraft-api:latest
    ports:
      - "8080:8080"
    env_file: .env
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      temporal:
        condition: service_started
    volumes:
      - github-keys:/keys:ro
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/healthz"]
      interval: 30s
      timeout: 5s
      retries: 3

  worker:
    image: ghcr.io/octokraft/octokraft-api:latest
    command: ["octokraft", "worker"]
    env_file: .env
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      temporal:
        condition: service_started
    volumes:
      - github-keys:/keys:ro
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

  frontend:
    image: ghcr.io/octokraft/octokraft-frontend:latest
    ports:
      - "3000:80"
    environment:
      - BACKEND_URL=http://api:8080
    depends_on:
      - api
    restart: unless-stopped

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

  redis:
    image: redis:7-alpine
    volumes:
      - redisdata:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
    restart: unless-stopped

  falkordb:
    image: falkordb/falkordb:latest
    volumes:
      - falkordata:/data
    restart: unless-stopped

  temporal:
    image: temporalio/auto-setup:latest
    environment:
      - DB=postgresql
      - DB_PORT=5432
      - POSTGRES_USER=octokraft
      - POSTGRES_PWD=octokraft
      - POSTGRES_SEEDS=postgres
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped

  temporal-ui:
    image: temporalio/ui:latest
    ports:
      - "8233:8080"
    environment:
      - TEMPORAL_ADDRESS=temporal:7233
    depends_on:
      - temporal
    restart: unless-stopped

volumes:
  pgdata:
  redisdata:
  falkordata:
  github-keys:
The worker service uses the same image as the api service with a different entrypoint. Workers process background tasks including code analysis, health assessments, and PR analysis.

Scaling

Adding Workers

The analysis workers handle the compute-intensive tasks. To process more repositories or PRs concurrently, add more worker replicas:
docker compose up -d --scale worker=3

Resource Allocation

For a team of 20-30 developers with 10-20 repositories:
ServiceCPUMemory
api2 cores2 GB
worker (each)2 cores2 GB
frontend0.5 cores256 MB
postgres2 cores2 GB
redis0.5 cores512 MB
falkordb1 core1 GB
temporal1 core1 GB

TLS Configuration

For production deployments, terminate TLS in front of Octokraft using a reverse proxy such as Nginx, Caddy, or Traefik. Example with Caddy:
octokraft.yourcompany.com {
    reverse_proxy localhost:3000
}

api.octokraft.yourcompany.com {
    reverse_proxy localhost:8080
}
Set FRONTEND_URL and BACKEND_URL to the public HTTPS URLs, and update CORS_ORIGINS accordingly.

Operations

Health Checks

# Simple health check
curl http://localhost:8080/healthz

# Detailed health with component status
curl http://localhost:8080/health/detailed

Logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f api
docker compose logs -f worker

Upgrades

# Pull latest images
docker compose pull

# Restart with new images
docker compose up -d

# Run any new migrations
docker compose exec api octokraft migrate up

Backups

Back up the PostgreSQL database regularly. The other services (Redis, FalkorDB) contain derived data that can be rebuilt from a fresh analysis.
docker compose exec postgres pg_dump -U octokraft octokraft > backup.sql

Troubleshooting

Check the logs for missing environment variables:
docker compose logs api
The API server will not start if any required variable is missing. The error message will indicate which variable is unset.
Verify that PostgreSQL is running and the connection string is correct:
docker compose exec postgres pg_isready -U octokraft
If using an external database, confirm that the DATABASE_URL is reachable from within the Docker network.
Verify the worker is running and connected to Temporal:
docker compose logs worker
Check the Temporal UI at http://localhost:8233 to see whether workflows are queued, running, or failing.
Verify that your server is reachable from the internet on port 443 (or whichever port you expose). GitHub must be able to reach your webhook endpoint.Check webhook delivery status in your GitHub App settings under Advanced > Recent Deliveries.
Scale the worker service to add more processing capacity:
docker compose up -d --scale worker=3
Also confirm that the AI model API is responsive. Slow model responses are the most common cause of slow analysis.