Docker Deployment
Deploy Agentfield agents and control plane using Docker
Docker Deployment
Deploy Agentfield agents and control plane using Docker
Overview
Docker provides a consistent deployment environment for Agentfield agents and the control plane. This guide covers both standalone agent deployment and full stack deployment with docker-compose.
Official docker-compose setup: Agentfield provides a production-ready docker-compose.yml in the GitHub repository with PostgreSQL + control plane configuration.
Essential Docker Environment Variables
These variables are critical for Docker deployments. See Environment Variables Reference for the complete list.
| Variable | Required | Example | Notes |
|---|---|---|---|
AGENTFIELD_SERVER | Yes | http://agentfield-server:8080 | Control plane URL (use service name in docker-compose) |
AGENT_CALLBACK_URL | Critical | http://agent-1:8000 | Where control plane reaches your agent. Must be network-accessible URL |
PORT | No | 8000 | Agent server port (default: 8000) |
AGENTFIELD_DATABASE_URL | Control Plane | postgres://user:pass@postgres:5432/agentfield | PostgreSQL connection (control plane only) |
Critical: Set AGENT_CALLBACK_URL correctly
Control plane must reach your agent. Don't use localhost or 127.0.0.1 in containers.
Common patterns:
- Docker Compose:
http://agent-service-name:8000 - Host + Docker:
http://host.docker.internal:8000 - Production:
https://agent-1.company.com
Test it: docker exec agentfield-server curl http://your-agent-url:8000/health
Quick Start
Single Agent Container
Deploy a single agent in a Docker container:
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy agent code
COPY . .
# Expose agent port
EXPOSE 8001
# Run agent
CMD ["python", "main.py"]# main.py
import os
from agentfield import Agent
app = Agent(
node_id="docker_agent",
agentfield_server=os.getenv("AGENTFIELD_SERVER", "http://localhost:8080"),
callback_url=os.getenv("AGENT_CALLBACK_URL")
)
@app.reasoner
async def process(text: str) -> str:
return await app.ai(user=text)
if __name__ == "__main__":
app.serve(
port=int(os.getenv("AGENT_PORT", 8001)),
host="0.0.0.0"
)Build and run:
# Build image
docker build -t my-agent .
# Run container
docker run -d \
--name my-agent \
-p 8001:8001 \
-e AGENTFIELD_SERVER=http://host.docker.internal:8080 \
-e AGENT_CALLBACK_URL=http://host.docker.internal:8001 \
-e OPENAI_API_KEY=your-api-key \
my-agentDocker Compose Setup
Full Stack Deployment
Deploy both the control plane and agents using docker-compose.
Official setup: Get the production-ready docker-compose.yml from github.com/Agent-Field/agentfield/deployments/docker/docker-compose.yml
Simplified example:
# docker-compose.yml
version: '3.9'
services:
# PostgreSQL Database (required)
postgres:
image: postgres:15-alpine
container_name: agentfield-postgres
environment:
- POSTGRES_DB=agentfield
- POSTGRES_USER=agentfield
- POSTGRES_PASSWORD=change-in-production
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
networks:
- agentfield-network
# Agentfield Control Plane
control-plane:
image: agentfield/control-plane:latest
container_name: agentfield-server
ports:
- "8080:8080"
environment:
- AGENTFIELD_POSTGRES_URL=postgres://agentfield:change-in-production@postgres:5432/agentfield
- AGENTFIELD_HTTP_ADDR=0.0.0.0:8080
depends_on:
- postgres
networks:
- agentfield-network
# Agent Node 1
agent-1:
build: ./agents/sentiment-analyzer
container_name: sentiment-agent
ports:
- "8001:8001"
environment:
- AGENTFIELD_SERVER=http://agentfield-server:8080
- AGENT_CALLBACK_URL=http://agent-1:8001
- OPENAI_API_KEY=${OPENAI_API_KEY}
depends_on:
- agentfield-server
networks:
- agentfield-network
# Agent Node 2
agent-2:
build: ./agents/data-processor
container_name: processor-agent
ports:
- "8002:8002"
environment:
- AGENTFIELD_SERVER=http://agentfield-server:8080
- AGENT_CALLBACK_URL=http://agent-2:8002
- AGENT_PORT=8002
- OPENAI_API_KEY=${OPENAI_API_KEY}
depends_on:
- agentfield-server
networks:
- agentfield-network
networks:
agentfield-network:
driver: bridge
volumes:
pgdata:
networks:
agentfield-network:
driver: bridge
Start the stack:
```bash
# Create .env file with secrets
echo "OPENAI_API_KEY=your-api-key" > .env
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop all services
docker-compose downEnvironment Variables
Required Variables
Prop
Type
Optional Variables
Prop
Type
Networking Scenarios
Scenario 1: Agent on Host, Control Plane in Docker
When the control plane runs in Docker but agents run on the host:
# Start control plane in Docker
docker run -d \
--name agentfield-server \
-p 8080:8080 \
agentfield/control-plane:latest
# Run agent on host
export AGENTFIELD_SERVER=http://localhost:8080
export AGENT_CALLBACK_URL=http://host.docker.internal:8001
python main.pyScenario 2: Both in Docker (Same Network)
When both control plane and agents run in Docker on the same network:
# docker-compose.yml
services:
agentfield-server:
image: agentfield/control-plane:latest
networks:
- agentfield-network
my-agent:
build: .
environment:
- AGENTFIELD_SERVER=http://agentfield-server:8080
- AGENT_CALLBACK_URL=http://my-agent:8001
networks:
- agentfield-network
networks:
agentfield-network:Use service names for internal communication.
Scenario 3: Production with External URLs
For production deployments with load balancers:
services:
my-agent:
build: .
environment:
- AGENTFIELD_SERVER=https://agentfield.company.com
- AGENT_CALLBACK_URL=https://agent-1.company.com
- OPENAI_API_KEY=${OPENAI_API_KEY}Health Checks
Add health checks to your agents:
# main.py
from agentfield import Agent
from fastapi import Response
app = Agent(node_id="my_agent")
@app.get("/health")
async def health_check():
"""Health check endpoint for Docker."""
return {"status": "healthy", "node_id": app.node_id}
@app.get("/ready")
async def readiness_check():
"""Readiness check - verify connection to control plane."""
try:
# Verify control plane connectivity
response = await app.http_client.get(
f"{app.agentfield_server}/health"
)
if response.status_code == 200:
return {"status": "ready"}
except Exception as e:
return Response(
content={"status": "not_ready", "error": str(e)},
status_code=503
)Docker health check configuration:
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8001/health || exit 1Production Best Practices
For production hardening (non-root users, resource limits, secrets management, logging), see the Production Hardening Guide.
Quick checklist:
- Use non-root user in Dockerfile
- Set resource limits (CPU, memory)
- Configure log rotation
- Use Docker secrets for API keys
- Add health checks to containers
Troubleshooting
Agent Cannot Connect to Control Plane
Symptom: Agent fails to register with control plane
Solutions:
- Verify network connectivity:
docker exec my-agent curl http://agentfield-server:8080/health- Check environment variables:
docker exec my-agent env | grep AGENTFIELD- Verify DNS resolution:
docker exec my-agent nslookup agentfield-serverControl Plane Cannot Reach Agent
Symptom: Executions fail with connection errors
Solutions:
- Verify
AGENT_CALLBACK_URLis set correctly:
# For host-based agents with Docker control plane
export AGENT_CALLBACK_URL=http://host.docker.internal:8001
# For Docker-based agents
export AGENT_CALLBACK_URL=http://agent-service-name:8001- Test callback URL from control plane:
docker exec agentfield-server curl http://host.docker.internal:8001/health- Check firewall rules and port bindings
Port Already in Use
Symptom: Address already in use error
Solutions:
- Find and stop conflicting container:
docker ps | grep 8001
docker stop <container-id>- Use different port:
docker run -p 8002:8001 my-agentScaling
# Scale control plane horizontally
docker-compose up --scale control-plane=3
# Scale specific agent independently
docker-compose up --scale support-agent=5Related Documentation
- Deployment Overview - Architecture and deployment patterns
- Kubernetes Deployment - Enterprise orchestration
- Managed Platforms - Railway, Render, Heroku
- Production Hardening - Security and resource limits
- Environment Variables Reference - Complete variables list