Open Connector
Self-Hosting

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

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)" >> .env

Then 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:

OK

Running 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:migrate

pnpm 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/
# OK

Open 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 -v

docker 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.

On this page