System configuration

Configure the LLM gateway, PeerDB replication, and Temporal workers for your self-hosted instance.

In this page

A few parts of the stack are configured outside .env: the LLM gateway needs a config.yaml listing its providers, PeerDB needs its replication mirrors running, and Temporal workers can be tuned for throughput. This page covers all three. Set your secrets and provider keys in Environment Variables first, since the config here references them.

LLM Gateway

The gateway is a Go proxy that routes every model call the platform makes. Its compose service is agentcc-gateway and its files live in agentcc-gateway/. It reads a config.yaml that lists which providers it may use and which models each exposes.

Warning

Model calls fail until this file exists. The gateway ships with config.example.yaml (OpenAI enabled) but not a live config.yaml. You create one in the steps below.

Copy the Example Config

cp agentcc-gateway/config.example.yaml \
   agentcc-gateway/config.yaml

Add Providers and Keys

Edit config.yaml: uncomment the providers you want and reference their keys with ${VAR} interpolation. Set the matching keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, …) in .env. See the provider examples below.

Mount the Config and Restart

Point the gateway volume at your config.yaml under the agentcc-gateway service in docker-compose.yml, adding a volumes: block if it has none:

services:
  agentcc-gateway:
    volumes:
      - ./agentcc-gateway/config.yaml:/app/config.yaml:ro
docker compose up -d --force-recreate agentcc-gateway

Confirm it came back with the config loaded:

curl -sf http://localhost:8090/healthz && docker compose logs --tail=20 agentcc-gateway

Warning

config.yaml is gitignored and holds live API keys. Treat it as a secret. Never commit it.

Provider Examples

providers:
  openai:
    api_key: "${OPENAI_API_KEY}"
    api_format: "openai"
    models: [gpt-4o, gpt-4o-mini]

  anthropic:
    api_key: "${ANTHROPIC_API_KEY}"
    api_format: "anthropic"
    models: [claude-opus-4-5, claude-sonnet-4-5]

  gemini:
    api_key: "${GOOGLE_API_KEY}"
    api_format: "gemini"
    models: [gemini-2.0-flash, gemini-1.5-pro]
providers:
  bedrock:
    api_key: "${AWS_SECRET_ACCESS_KEY}"
    api_format: "bedrock"
    region: "${AWS_REGION}"
    access_key: "${AWS_ACCESS_KEY_ID}"
    models: [anthropic.claude-3-5-sonnet-20241022-v2:0]
providers:
  vertex:
    base_url: "https://us-central1-aiplatform.googleapis.com"
    api_key: "${GOOGLE_ACCESS_TOKEN}"
    api_format: "gemini"
    headers:
      x-gcp-project: "${GCP_PROJECT_ID}"
      x-gcp-location: "us-central1"
    models: [gemini-2.0-flash-001]

Vertex uses a Bearer token, not a static API key. Rotate GOOGLE_ACCESS_TOKEN with a sidecar that calls gcloud auth print-access-token.

For routing rules, rate limits, caching, and the full config reference, see Agent Command Center → Self-Hosted.

PeerDB Replication

PeerDB only runs under the full profile, so if none of this appears on your host, that’s why. When it is on, it continuously replicates Postgres tables into ClickHouse (change-data-capture) so dataset and simulation analytics stay fast. It runs on its own, and the only thing you typically touch is a first-boot timing fix.

Warning

First-boot timing. peerdb-init runs the moment the stack starts, sometimes before Django has finished its migrations. If mirrors show “not started” in the PeerDB UI, re-run init once the backend is up:

docker compose logs -f backend                       # wait for "Application startup complete"
docker compose run --rm peerdb-init                  # re-run init

Verify at http://localhost:3001. Mirrors should move to running within seconds. Re-run the same init command after any upgrade that changes replicated tables.

Temporal Workers

Temporal runs the platform’s background jobs and evaluation pipelines. How those jobs are distributed across workers depends on one flag.

All-queue (default). One worker polls every task queue. Controlled by TEMPORAL_ALL_QUEUES=true in .env. This is the right setup for most self-hosted deployments.

Per-queue. Reach for this when one slow job type is holding up the rest. It takes both settings: start the workers profile (or the dev overlay) to create the six dedicated workers, and set TEMPORAL_ALL_QUEUES=false so the always-on worker stops polling every queue alongside them.

ServiceQueueTypical concurrency
worker-defaultdefault100
worker-tasks-stasks_s200
worker-tasks-ltasks_l50
worker-tasks-xltasks_xl10
worker-trace-ingestiontrace_ingestion100
worker-agent-compassagent_compass50

The concurrency column shows each service’s shipped default. TEMPORAL_MAX_CONCURRENT_ACTIVITIES and TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS in .env apply to every worker at once, so use them to move the whole fleet rather than one queue. The Temporal UI runs at http://localhost:8085 under the observability profile, and in dev mode.

Dive Deeper

Was this page helpful?

Questions & Discussion