Host in production
Overview
This guide covers a single-VM deployment — one host running all containers behind a Caddy reverse proxy with automatic TLS. This is the recommended starting point for small to medium production workloads before you need horizontal scaling.
What this guide covers:
- Docker Compose service layout (gateway + your agentic API service + optional OTLP collector)
- Caddy reverse proxy with automatic Let’s Encrypt TLS
- DNS and firewall prerequisites
- Verification and log tailing
What this guide does not cover:
- Kubernetes or Helm (see PI5-yaa OR community contribution welcome — Helm chart)
- Cloud-provider-specific infrastructure (yaagents is cloud-agnostic; no AWS/GCP/Azure details here)
- Multi-VM horizontal scaling (that’s the Helm/K8s path)
Architecture target
flowchart LR Internet --> Caddy["Caddy\n(reverse proxy + TLS)"] Caddy --> GW["yaagents-gateway\n(:8120)"] GW --> SVC["Your agentic\nAPI service\n(:8121)"] GW --> OA["otel-collector\n(:4317, optional)"]The Caddy proxy terminates TLS and forwards to the yaagents gateway on port 8120. The gateway routes to your agentic API service. All containers run on the same Docker bridge network — no inter-container traffic leaves the host.
For Kubernetes deployments, see: PI5-yaa OR community contribution welcome — Helm chart. A Helm chart is on the public roadmap (GitHub Issues).
Prerequisites
Before starting:
- A Linux VM (1 vCPU, 1 GB RAM minimum; 2+ recommended for production)
- Docker Engine 24+ and Docker Compose v2 installed
- A domain name with DNS A record pointing at the VM’s public IP
- TCP ports 80 and 443 open inbound (for Let’s Encrypt and HTTPS traffic)
- Your agentic API service container image (or build it locally from
examples/store/)
Step-by-step
-
Clone the deploy repository or create a deployment directory.
If starting from scratch, create a directory on the VM:
Terminal window mkdir -p ~/yaagents-prod && cd ~/yaagents-prod -
Write
docker-compose.yml.Create
docker-compose.ymlwith the gateway, your service, and Caddy:services:gateway:image: ghcr.io/ai-mpathyminds/yaagents-gateway:0.3.0restart: unless-stoppedports:- "127.0.0.1:8120:8120"environment:GATEWAY_CONFIG: /etc/yaagents/gateway.yamlvolumes:- ./gateway.yaml:/etc/yaagents/gateway.yaml:rohealthcheck:test: ["CMD", "wget", "-qO-", "http://localhost:8120/healthz"]interval: 10stimeout: 5sretries: 3my-service:image: my-registry/my-agentic-service:latestrestart: unless-stoppedports:- "127.0.0.1:8121:8121"environment:SERVICE_PORT: "8121"healthcheck:test: ["CMD", "wget", "-qO-", "http://localhost:8121/readyz"]interval: 10stimeout: 5sretries: 3caddy:image: caddy:2-alpinerestart: unless-stoppedports:- "80:80"- "443:443"volumes:- ./Caddyfile:/etc/caddy/Caddyfile:ro- caddy_data:/data- caddy_config:/configvolumes:caddy_data:caddy_config: -
Write
Caddyfile.Replace
api.yourdomain.comwith your domain:api.yourdomain.com {reverse_proxy gateway:8120}Caddy handles TLS certificate provisioning automatically via Let’s Encrypt. No certificate files to manage.
-
Write
gateway.yaml.Minimal gateway config pointing at your service:
upstream:url: http://my-service:8121plugins:token-validator:enabled: trueissuers:- iss: https://auth.yourdomain.com/realms/yourealmjwks_uri: https://auth.yourdomain.com/realms/yourealm/protocol/openid-connect/certstenant-injector:enabled: trueprincipal:claim: sublookup:url: http://my-service:8121/internal/tenant/{principal}timeout_ms: 500otel-audit:enabled: trueexporter: stdoutSee the Plugin overview for all plugin configuration options.
-
Start the stack.
Terminal window docker compose up -dOn first start, Caddy automatically fetches a Let’s Encrypt certificate. This requires ports 80 and 443 to be open and DNS to resolve to the VM.
-
Verify HTTPS.
Wait 30–60 seconds for the certificate to provision, then:
Terminal window curl -sf https://api.yourdomain.com/healthz# Expected: {"status":"ok"}curl -sf https://api.yourdomain.com/readyz# Expected: {"status":"ok"}If the gateway returns
200, TLS is working and the gateway is healthy.
Going to production
Once the stack is running, consider these operational notes:
- Log aggregation:
docker compose logs -f gateway my-servicetails all logs. For production, ship stdout to a log aggregator (Loki, Datadog, CloudWatch) by configuring the Docker logging driver indocker-compose.yml. - Metrics: the gateway exposes Prometheus metrics at
http://localhost:8120/metrics. Scrape this with Prometheus or ship via the OTLP collector (otel-auditplugin inexporter: otlpmode). - Backups: no persistent gateway state to back up. Back up
gateway.yamlalongside your application data. - Scaling: single-VM scaling means a bigger VM. Horizontal scaling requires container orchestration — see below.
- Kubernetes / Helm chart: a Helm chart for Kubernetes deployments is on the roadmap. PI5-yaa OR community contribution welcome — see GitHub Issues for the tracking issue. The yaagents architecture is stateless-gateway-friendly; horizontal scaling needs only a shared session source (already handled by JWT validation, not gateway state).