Self-host with Docker Compose
CodeLoop runs end-to-end on your own infrastructure with a single docker compose up. This page is the runbook for the stack in deploy/self-hosted/ in the CodeLoop monorepo:
- Postgres — runs, lineage, gate history, billing tables.
- Redis — usage queue, anti-abuse counters, rate limits.
- MinIO — S3-compatible artifact storage (screenshots, videos, logs).
- API (
codeloop-backend-api) — auth, usage, badge endpoints. Configured forCODELOOP_MODE=localso it skips Stripe + Heroku-only paths. - Dashboard — local artifact viewer on port 3737.
Prerequisites
- Docker 24+ and Docker Compose v2.
- Outbound HTTPS (only used by the CLI / MCP server when calling your self-hosted API).
- A vision model API key if you want
codeloop_visual_review/codeloop_design_compareto do remote analysis. CodeLoop itself stays zero-LLM-cost; the visual reasoning is delegated to your AI agent unless you wire one up here.
Bring up the stack
# from the CodeLoop monorepo
cd deploy/self-hosted
cp .env.example .env
# edit .env to set strong values for:
# POSTGRES_PASSWORD, MINIO_ROOT_PASSWORD, JWT_SECRET
docker compose up -d
docker compose psVerify each service is healthy:
http://localhost:3000/health— APIhttp://localhost:3737— dashboardhttp://localhost:9001— MinIO console (login withMINIO_ROOT_USER/MINIO_ROOT_PASSWORD)
Point the CLI / MCP server at your stack
# in the project where you want CodeLoop to verify
export CODELOOP_API_URL="http://your-api-host:3000"
export CODELOOP_MODE=local
export CODELOOP_API_KEY="cl_test_self_hosted"
npx codeloop init
npx codeloop verifyIn local mode the API skips remote billing validation and any cl_test_* key is accepted, so your team can issue their own keys without contacting codeloop.tech.
Environment variables
| Variable | Default | What it controls |
|---|---|---|
POSTGRES_PASSWORD | codeloop_dev | Postgres superuser password. Change before going live. |
MINIO_ROOT_USER / MINIO_ROOT_PASSWORD | codeloop / codeloop_dev | MinIO root credentials. |
MINIO_BUCKET | codeloop-artifacts | Bucket for run artifacts. |
JWT_SECRET | change-me-in-production | Used by the API for signed tokens. Must be rotated. |
API_PORT / DASHBOARD_PORT | 3000 / 3737 | Host ports for the API and dashboard. |
POSTGRES_PORT / REDIS_PORT | 5432 / 6379 | Override if those ports are already in use. |
Going to production
- Replace the bundled Postgres / Redis / MinIO with managed services (RDS, ElastiCache, S3) and override the corresponding env vars.
- Front the API with a reverse proxy (Nginx, Caddy, Cloudflare) that terminates TLS.
- Restrict the dashboard to a private network or put it behind your SSO; the dashboard has no built-in auth.
- Schedule the equivalent of scheduled-e2e.yml on your runners to validate the deployment weekly.