Start the complete Agent Barn development environment with Docker. When you finish, you will have the Agent Barn web app, Product API, Ingest API, background worker, LiteLLM proxy, PostgreSQL, Redis, and a local Kubernetes cluster running on your computer.
The full-stack workflow runs application services in Docker and Agent workloads in a local k3d cluster. You do not need to install k3d or Helm on your computer.
What you will accomplish
By the end of this guide, you will be able to:
- Open Agent Barn at
http://localhost:3000 - Sign in as the bootstrap Platform Administrator
- Create an Organization
- Run Agents inside the local Kubernetes cluster
- Route model requests through the local LiteLLM proxy
- Receive Agent conversation and Tool Call telemetry
- Stop and resume the environment without losing local database data
Before you begin
Required software
Install the following tools:
- Git
- Docker with Docker Compose v2
- Bash
kubectl
Docker Desktop is the simplest option on macOS and Windows. On Windows, run the repository through WSL2 with Docker Desktop using its Linux-container backend.
The full Docker workflow does not require a host installation of Python, Node.js, uv, pnpm, k3d, or Helm. Those tools are needed only for native development, testing, or selected maintenance commands.
Required accounts and credentials
You need:
- An OpenRouter API key
- A GitHub personal access token with read access to
aai-labs/aai-cli
The GitHub token is used while building the local Agent runtime images.
Local ports
Make sure these default ports are available:
| Port | Service |
|---|---|
3000 | Agent Barn web app |
5432 | PostgreSQL |
6379 | Redis |
7070 | LiteLLM |
8000 | Product API |
8001 | Ingest API |
16443 | Local Kubernetes API |
Clone the repository
git clone https://github.com/aai-labs/agent-barn.git
cd agent-barnThe GitHub repository uses the current agent-barn name. The local Kubernetes namespaces intentionally retain the historical agent-farm naming.
Create the local configuration
Copy the tracked environment template:
cp .env.spec .envOpen .env in your editor. The file documents every available setting.
Replace the placeholder values in the following groups.
Database and application
POSTGRES_USER=agentbarn
POSTGRES_PASSWORD=<local-database-password>
POSTGRES_DB=agentbarn
POSTGRES_PORT=5432
API_PORT=8000
ENVIRONMENT=local
UI_APP_URL=http://localhost:3000
SECRET_SIGNING_KEY=<random-signing-key>
PLATFORM_ADMIN_CREDENTIALS=[email protected]:<secure-password>The Platform Administrator password must contain:
- At least eight characters
- An uppercase letter
- A lowercase letter
- A digit
Generate a random signing key with:
openssl rand -hex 32Do not use the generated signing key as the Platform Administrator password.
Credential encryption
Set a Fernet key for encrypting Agent credentials:
AGENT_TOKEN_ENCRYPTION_KEY=<fernet-key>One way to generate a Fernet key in a Python environment with cryptography installed is:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"Keep this key stable. Changing it later prevents Agent Barn from decrypting credentials stored under the previous key.
Model routing
OPENROUTER_API_KEY=<openrouter-api-key>
LITELLM_MASTER_KEY=<stable-litellm-master-key>Generate a local LiteLLM master key with:
printf 'sk-%s\n' "$(openssl rand -hex 16)"Set the generated value once and keep it stable. LiteLLM uses it to protect the virtual keys it stores. Changing it between runs breaks Agents created with keys protected by the previous value.
Agent runtime images
Read the versions pinned by the repository:
printf 'OpenClaw: '
cat openclaw-base/VERSION
printf 'Hermes: '
cat hermes-base/VERSIONSet both image references using those exact tags:
OPENCLAW_IMAGE=agentbarn-openclaw-base:<openclaw-version>
HERMES_IMAGE=agentbarn-hermes-base:<hermes-version>
GH_TOKEN=<github-personal-access-token>The image tag must match the corresponding VERSION file. Startup stops with a clear error when the values do not match.
Start Agent Barn
Start the complete environment in detached mode:
./run.sh --detachAlternatively, run the following command to follow application logs after startup:
./run.shPressing Ctrl+C stops following the logs but leaves the stack running.
The startup script:
- Validates Docker and the required environment values.
- Starts LiteLLM and its PostgreSQL database.
- Creates or resumes the local k3d cluster.
- Writes host and container kubeconfig files under
.k3d/. - Creates the
agent-farmnamespace and LiteLLM Secret. - Builds and imports the pinned Hermes and OpenClaw images.
- Starts PostgreSQL and Redis.
- Applies database migrations.
- Builds and starts the Product API, Ingest API, worker, and web app.
- Configures the API container to reach the local Kubernetes cluster.
Verify the environment
Check the containers
docker compose -f compose.yml psExpected: The database, Redis, Product API, worker, web app, LiteLLM, and LiteLLM database are running.
Check the Product API
curl -fsS http://localhost:8000/api/v1/healthExpected response:
{"status":"ok","db":"connected"}This confirms that the Product API can reach PostgreSQL.
Check the Ingest API
curl -sS -o /dev/null -w '%{http_code}\n' \
http://localhost:8001/ingest/v1/openapi.jsonExpected result:
200The Ingest API stores Agent conversations and Tool Call activity. An Agent can run without visible activity when this path is unavailable, so verify it before troubleshooting the Activity UI.
Check the Kubernetes cluster
kubectl \
--kubeconfig .k3d/kubeconfig-host.yaml \
get namespace agent-farmExpected: The agent-farm namespace is present.
Inspect all local Kubernetes workloads:
kubectl \
--kubeconfig .k3d/kubeconfig-host.yaml \
get pods -ASign in
Open:
http://localhost:3000 Sign in with the email and password from PLATFORM_ADMIN_CREDENTIALS in .env.
What is running
| Component | Local address | Responsibility |
|---|---|---|
| Web app | http://localhost:3000 | User interface |
| Product API | http://localhost:8000/api/v1 | Product and administration requests |
| Ingest API | http://localhost:8001/ingest/v1 | Runtime conversation and Tool Call telemetry |
| LiteLLM | http://localhost:7070 | Model routing and per-Agent key management |
| Kubernetes API | https://localhost:16443 | Local Agent workloads |
| PostgreSQL | localhost:5432 | Product state |
| Redis | localhost:6379 | Domain Event delivery transport |
Stop or resume the environment
Stop the application containers and local cluster:
./stop.shThis preserves:
- PostgreSQL and Redis volumes
- The local k3d cluster
- Previously imported Agent images
Resume with:
./run.sh --detachTo stop the stack and delete the k3d cluster:
./stop.sh --cleanTroubleshooting
Startup reports missing environment variables
./run.sh validates required values before starting services. Read the reported variable names, replace their empty or placeholder values in .env, and run the command again.
Do not remove a variable from the validation list to bypass the error.
Startup fails while creating the Platform Administrator
Check PLATFORM_ADMIN_CREDENTIALS. Its password must contain at least eight characters, an uppercase letter, a lowercase letter, and a digit.
The high-level error can appear as:
500: Error while initializing startup dataThe API log immediately before that message contains the underlying validation error.
Runtime image tags do not match
OPENCLAW_IMAGE and HERMES_IMAGE must end with the versions stored in:
openclaw-base/VERSION
hermes-base/VERSIONUpdate .env so each tag matches its file exactly.
Runtime-image build cannot read aai-cli
Confirm that GH_TOKEN is a GitHub personal access token with read access to aai-labs/aai-cli.
The runtime-image build passes this value as a Docker build secret. Do not place it in a Dockerfile or command argument.
The API reports an invalid kubeconfig
The Docker workflow should add this value to .env automatically:
API_K8S_KUBECONFIG_PATH=/app/.k3d/kubeconfig-internal.yamlConfirm the file exists locally:
ls -l .k3d/kubeconfig-internal.yamlIf the cluster was created before the current TLS configuration, rebuild it:
./stop.sh --clean
./run.sh --detachAn Agent is stuck in ImagePullBackOff
Confirm that the image reference in .env matches the imported image and the repository VERSION file.
Reload missing images with:
bash docker/k3d/k3d-load-images.shThe image build stalls while downloading Debian packages
Retry with a full Debian mirror:
APT_MIRROR=mirror.csclub.uwaterloo.ca \
bash docker/k3d/k3d-load-images.shThe mirror must provide both Debian and Debian Security repositories.
An Agent runs but Activity remains empty
Verify that the Ingest API returns 200 and that port 8001 is reachable from the local cluster.
Agent pods use:
http://host.docker.internal:8001/ingest/v1On native Linux, also verify that the host firewall permits traffic from the k3d bridge network.
Agent pods are killed with exit code 137
Exit code 137 or OOMKilled normally means the Docker environment ran out of memory.
Inspect current usage:
docker stats --no-streamIncrease the Docker memory allocation or stop unrelated workloads before retrying.