Docker Compose
Run Open Connector locally with Docker Compose.
Docker Compose is a fast way to get Open Connector running. There is no published Docker image — the server image is built from source from apps/server/Dockerfile, with the monorepo root as the build context. This setup is ideal for local development, internal tooling, or small self-hosted deployments where you do not need auto-scaling.
The root docker-compose.yml in the repository is infra-only (Postgres, MinIO, and a grafana/otel-lgtm backend) — it does not run the server. Bring it up with pnpm infra:up (or just Postgres with pnpm db:start) and run the server separately. The compose file below is a self-contained variant that also builds and runs the server from source.
Prerequisites
- Docker Desktop (macOS/Windows) or Docker Engine + Compose v2 (Linux)
- A clone of the
openconnector-dev/openconnectorrepository (the build context) opensslfor generating secret keys
Complete docker-compose.yml
From inside your clone of the repository, save this file as docker-compose.selfhost.yml at the repo root (the build.context must be the repo root so the Dockerfile can copy the whole workspace):
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: open_connector
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
server:
# Built from source — there is no published image.
build:
context: .
dockerfile: apps/server/Dockerfile
restart: unless-stopped
ports:
- "3000:3000"
env_file:
- .env
environment:
DATABASE_URL: postgres://postgres:postgres@postgres:5432/open_connector
NODE_ENV: production
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:Environment variables
Create a .env file in the same directory. Generate strong secrets with openssl:
echo "BETTER_AUTH_SECRET=$(openssl rand -base64 32)" >> .env
echo "CONNECTOR_ENCRYPTION_KEY=$(openssl rand -base64 32)" >> .envThen open .env and add the remaining variables:
# --- Required secrets (generated above) ---
BETTER_AUTH_SECRET=<your-generated-value>
CONNECTOR_ENCRYPTION_KEY=<your-generated-value>
# --- Required URLs ---
# The URL of the API server itself (used for OAuth callback construction)
BETTER_AUTH_URL=http://localhost:3000
# The URL of the dashboard app (used for CORS)
CORS_ORIGIN=http://localhost:3001
# The marketing-site base URL (used for waitlist confirm links) — REQUIRED
WEB_URL=http://localhost:3002
# --- Email (optional — when unset, a log mailer prints the confirm link) ---
# RESEND_API_KEY=re_...
# [email protected]Add .env to your .gitignore before committing. These secrets must never appear in version control.
Starting the stack
# Build the server image and start Postgres + the API server in the background
docker compose -f docker-compose.selfhost.yml up -d --build
# View logs
docker compose -f docker-compose.selfhost.yml logs -f server
# Check that the server is healthy (the root route is the liveness probe)
curl http://localhost:3000/A healthy server returns:
OKRunning database migrations
The server does not automatically run migrations on startup. Run them once after the first boot, and after each upgrade, from the repo root with DATABASE_URL set:
DATABASE_URL='postgres://postgres:postgres@localhost:5432/open_connector' pnpm db:migratepnpm db:push is the dev/push variant (applies the schema diff without generating migration files). Provider catalog rows (GitHub, Telegram) are seeded automatically on server boot (seedProviders) — you do not seed connectors manually.
Verifying the installation
Check the health endpoint
curl http://localhost:3000/
# OKOpen the dashboard
Navigate to http://localhost:3001 in your browser (if you have also started the dashboard app), or use the API directly:
curl "http://localhost:3000/api/v1/toolkits?limit=1" \
-H "x-api-key: <your-agent-key>"Create your first organization
POST to the API or use the dashboard to create an organization, a project, and mint your first agent API key.
Stopping and resetting
# Stop containers (preserves data)
docker compose -f docker-compose.selfhost.yml stop
# Stop and remove containers (preserves volume data)
docker compose -f docker-compose.selfhost.yml down
# Stop, remove containers AND wipe the database volume
docker compose -f docker-compose.selfhost.yml down -vdocker compose down -v deletes all stored credentials and audit logs. Only use it when you want a completely fresh start.
Production considerations
Docker Compose is convenient but has limitations for production:
- No automatic restarts on host reboot (add a systemd service or use
restart: always) - No rolling updates — updating the image requires a brief downtime
- Single host — no horizontal scaling
- Backups — you are responsible for Postgres backups (pg_dump or volume snapshots)
For the repository's supported production topology, use Deploy to AWS.