Running autonomous AI agents in production requires robust infrastructure, proper network isolation, automated TLS certificates, and secure access control. In this guide, we walk through deploying Hermes Agent inside Docker containers using Docker Compose, fronted by a Caddy reverse proxy for automated HTTPS management, and integrated with Keycloak for robust identity and access management.
Architecture Overview
Our stack consists of three primary services running on a shared Docker bridge network (multiwp):
- Caddy (v2): Acts as our edge reverse proxy, handling incoming HTTP/HTTPS traffic on ports
80and443, automatically provisioning SSL/TLS certificates via Let’s Encrypt, and routing traffic to internal container endpoints. - Keycloak: Provides authentication and identity management (
oauth.example.com). - Hermes Agent: The core autonomous agent container (
nousresearch/hermes-agent:latest), running the gateway service with dashboard capabilities enabled (hermes.example.com).
1. Requirements
There a few requirements to implement this stack:
- A Linux server (VPS) to host the stack. This articles describes setting up hermes on the public internet. There are plenty of guides on the Internet how to acquire a VPS server.
- Make sure the servers is provisioned with a public IP address, this is important for the step above.
- Docker and Docker compose installed on the VPS
Once the requirements are fulfilled, proceed with the post.
2. Setting Up DNS
Before deploying your containers, configure your domain’s DNS records to point to your server’s public IP address using any provider of choice (e.g., Cloudflare, Route53, Namecheap, DigitalOcean DNS). Refer to the provider’s documentation to update A records.
*** MAKE SURE TO REPLACE example.com WITH A DOMAIN YOU ACTUALLY OWN ***
Create A Records for your services:
hermes.example.com→ Points to your server public VPS server IPoauth.example.com→ Points to your server public VPS server IP
3. Docker Compose Configuration
The following docker-compose.yml file defines our network, resource limits, persistent volumes, and container settings:
services:
caddy:
container_name: caddy
image: caddy:2
deploy:
resources:
limits:
memory: 256M
reservations:
memory: 128M
depends_on:
- keycloak
- hermes
restart: always
volumes:
- caddydata:/data
- type: bind
source: ./caddy/etc/caddy
target: /etc/caddy
ports:
- "80:80"
- "443:443"
networks:
multiwp:
ipv4_address: 172.18.0.10
keycloak:
image: keycloak/keycloak:latest
container_name: keycloak-auth
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: THESECUREPASSWORD
KC_HOSTNAME: https://oauth.example.com
KC_HTTP_ENABLED: "true"
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M
restart: always
volumes:
- keycloak_data:/opt/keycloak/data/
networks:
multiwp:
ipv4_address: 172.18.0.20
command:
- start
- --proxy-headers=xforwarded
hermes:
image: nousresearch/hermes-agent:latest
container_name: hermes
restart: always
command: gateway run
volumes:
- /opt/hermes-stack/hermes-data:/opt/data
environment:
- HERMES_DASHBOARD=1
deploy:
resources:
limits:
memory: 4G
reservations:
memory: 1G
networks:
multiwp:
ipv4_address: 172.18.0.30
volumes:
caddydata:
keycloak_data:
networks:
multiwp:
internal: false
ipam:
config:
- subnet: 172.18.0.0/16
4. Caddy Reverse Proxy Configuration
Caddy makes TLS termination and proxy routing effortless. Create your Caddyfile at ./caddy/etc/caddy/Caddyfile:
{
on_demand_tls {
ask http://localhost:5555/
}
}
http://localhost:5555 {
respond 200
}
# Keycloak SSO
oauth.example.com {
tls {
on_demand
}
reverse_proxy http://keycloak:8080
}
# Hermes Agent Dashboard & Gateway
hermes.example.com {
tls {
on_demand
}
reverse_proxy http://hermes:9119
}
5. Deployment & Verification
- Create your directory structure and save the configuration files:
mkdir -p /opt/hermes-stack/caddy/etc/caddy cd /opt/hermes-stack - Place
docker-compose.ymlin/opt/hermes-stack/andCaddyfilein/opt/hermes-stack/caddy/etc/caddy/. - Spin up the containers:
docker compose up -d - Verify logs to ensure all services initialized correctly:
docker compose logs -f
You now have a fully containerized, secure Hermes Agent deployment running behind Caddy with automated HTTPS and Keycloak authentication ready for production use!
6. Loggin in to Keycloak and Hermes and finish the initial Setup
At this point, you can access the two domains from your browser oauth.example.com and hermes.example.com.
Setting up keycloak and hermes will be discuss in the Part 2 of this post. Coming soon…