Host it: docker-compose¶
The middle ground. One host, three containers — orchestrator, sandbox-agent, Redis — and your webhooks pointed at the orchestrator. Easiest path to a "real" Agent Smith deployment.
What this gets you¶
- Long-running orchestrator. Webhooks work, polling works, jobs queue in Redis and survive restarts.
- Per-repo sandboxes. The orchestrator creates Docker containers on demand, one per repo per run, using the toolchain image you've configured.
- A persistent Redis. In-flight jobs, claim locks, leader leases, the run-id high-water mark — all there.
The orchestrator pod is single-replica in this setup. For multi-replica you want Kubernetes.
The compose file¶
docker-compose.yml:
services:
orchestrator:
image: holgerleichsenring/agent-smith:0.60.1
restart: unless-stopped
ports:
- "8080:8080" # webhook endpoint
environment:
AGENTSMITH_CONFIG: /etc/agent-smith/agentsmith.yml
REDIS_URL: redis://redis:6379
AZURE_OPENAI_API_KEY: ${AZURE_OPENAI_API_KEY}
AZURE_DEVOPS_TOKEN: ${AZURE_DEVOPS_TOKEN}
SANDBOX_TYPE: docker
DOCKER_HOST: unix:///var/run/docker.sock
volumes:
- ./agentsmith.yml:/etc/agent-smith/agentsmith.yml:ro
- ./runs:/var/lib/agent-smith/runs # run directories
- ./skills:/var/lib/agentsmith/skills # skills cache
- /var/run/docker.sock:/var/run/docker.sock # orchestrator creates sandbox containers
depends_on:
redis:
condition: service_healthy
# Sandbox-agent image is referenced by the orchestrator when it creates
# per-repo sandbox containers. We don't run it as a service — we just
# make sure the image is pulled so the orchestrator can use it.
sandbox-agent-pull:
image: holgerleichsenring/agent-smith-sandbox-agent:0.60.1
command: ["true"]
restart: "no"
redis:
image: redis:7
restart: unless-stopped
command: ["redis-server", "--appendonly", "yes"]
volumes:
- ./redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
Drop your agentsmith.yml (full TodoList example on the Azure DevOps tracker page) next to this compose file, set the env vars, bring it up:
export AZURE_OPENAI_API_KEY=...
export AZURE_DEVOPS_TOKEN=...
docker compose pull
docker compose up -d
# Watch the orchestrator come up
docker compose logs -f orchestrator
Webhooks¶
The orchestrator listens on port 8080. For a public webhook URL you need to put a reverse proxy in front (or Cloudflare Tunnel / ngrok for dev). The simplest production setup is Caddy:
Caddyfile:
# add to docker-compose.yml
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
Caddy gets you automatic Let's Encrypt TLS. Point your DNS at the host, point the tracker webhooks at https://agent-smith.your-domain.example/webhooks/{tracker-type}, done.
Storage¶
Three volumes the orchestrator writes to:
./runs/— run directories accumulate here. Manageable size (a few MB per run). Keep them; the wiki-compile feature uses the history../skills/— the skills cache. Pulled from theagent-smith-skillsrepo at startup; rebuilt whenskills.versionchanges../redis-data/— Redis append-only log. Small unless you have very long runs.
For a real production setup put these on a persistent volume (or named Docker volume) so a host rebuild doesn't lose state.
Logs¶
Orchestrator logs are structured (JSON if LOG_FORMAT=json is set, otherwise human-readable). Per-run logs also land in the run directory's result.md.
Updating¶
# Update the version pin in both places
sed -i 's/0.60.1/0.60.2/g' docker-compose.yml
sed -i 's/0.60.1/0.60.2/g' agentsmith.yml # the `sandbox.agent_version` + `orchestrator.version`
docker compose pull
docker compose up -d
The two version numbers (image tag + agentsmith.yml sandbox/orchestrator versions) must match — that's the upgrade contract. Skills version (skills.version) is independent; bump it whenever you want.
What this isn't¶
- It's not HA. One orchestrator, one Redis. If the orchestrator dies in the middle of a run, the run gets restarted from the queue on the next startup (the
StaleJobDetectornotices and re-enqueues). - It's not auto-scaling. For more concurrent runs, more replicas, you want Kubernetes.
Next¶
- Kubernetes — when one orchestrator isn't enough.
- Webhooks — wiring the tracker to your new public URL.
- First run — but from the host this time, via the tracker.