ConfigurationAgents
Agents
Agent Mode allows running Drydock in a distributed manner across multiple Docker hosts.
The Agent Mode allows running drydock in a distributed manner.
- Agent Node: Runs near the Docker socket (or other container sources). It performs discovery and update checks.
- Controller Node: The central instance. It manages its own local watchers AND connects to remote Agents. It aggregates containers from Agents, and handles persistence, UI, and Notifications.
Architecture
The Controller connects to one or more Agents via HTTP/HTTPS. The Agent pushes real-time updates (container changes, new versions found) to the Controller using Server-Sent Events (SSE).
Agent Configuration
To run drydock in Agent mode, start the application with the --agent command line flag.
Agent Environment Variables
| Env var | Required | Description | Default |
|---|---|---|---|
DD_AGENT_SECRET | 🔴 | Secret token for authentication (must match Controller configuration) | |
DD_AGENT_SECRET_FILE | ⚪ | Path to file containing the secret token | |
DD_SERVER_PORT | ⚪ | Port to listen on | 3000 |
DD_SERVER_TLS_* | ⚪ | Standard Server TLS options | |
DD_WATCHER_{name}_* | 🔴 | Watcher configuration (At least one is required) | |
DD_TRIGGER_DOCKER_{name}_* | ⚪ | Docker trigger for container updates (required to update containers from UI/API) | |
DD_REGISTRY_{name}_* | ⚪ | Registry configuration (For update checks) |
Watcher and trigger env vars use different naming patterns. Watchers are
DD_WATCHER_{name}_{option} (no provider segment — Docker is the only watcher type). Triggers are DD_TRIGGER_DOCKER_{name}_{option} (provider segment required). A common mistake is writing DD_TRIGGER_DOCKER_PRUNE=true (missing the name) — this creates a broken trigger named "prune" instead of a trigger with PRUNE=true. Use DD_TRIGGER_DOCKER_{name}_PRUNE=true instead.Agent Example (Docker Compose)
This example uses a socket proxy for secure Docker socket access. Agents also support direct socket mount and remote TLS connections.
services:
drydock-socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
container_name: drydock-socket-proxy
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- IMAGES=1
- EVENTS=1
- POST=1
- DELETE=1
- NETWORKS=1
- VOLUMES=1
healthcheck:
test: wget --spider http://localhost:2375/version || exit 1
interval: 5s
timeout: 3s
retries: 3
start_period: 5s
drydock-agent:
image: codeswhat/drydock
command: --agent
depends_on:
drydock-socket-proxy:
condition: service_healthy
ports:
- "3000:3000"
environment:
# Shared secret (must match controller's DD_AGENT_{name}_SECRET)
- DD_AGENT_SECRET=mysecretkey
# Watcher — discovers containers on this host
- DD_WATCHER_LOCAL_HOST=drydock-socket-proxy
- DD_WATCHER_LOCAL_PORT=2375
# Docker trigger — allows updating containers from UI/API
- DD_TRIGGER_DOCKER_LOCAL_PRUNE=trueController Configuration
To connect a Controller to an Agent, use the DD_AGENT_{name}_* environment variables.
Controller Environment Variables
| Env var | Required | Description | Default |
|---|---|---|---|
DD_AGENT_{name}_SECRET | 🔴 | Secret token to authenticate with the Agent | |
DD_AGENT_{name}_SECRET_FILE | ⚪ | Path to file containing the secret token | |
DD_AGENT_{name}_HOST | 🔴 | Hostname or IP of the Agent | |
DD_AGENT_{name}_PORT | ⚪ | Port of the Agent | 3000 |
DD_AGENT_{name}_CAFILE | ⚪ | CA certificate path for TLS connection | |
DD_AGENT_{name}_CERTFILE | ⚪ | Client certificate path for TLS connection | |
DD_AGENT_{name}_KEYFILE | ⚪ | Client key path for TLS connection |
Controller Example (Docker Compose)
services:
drydock-controller:
image: codeswhat/drydock
environment:
- DD_AGENT_REMOTE1_HOST=192.168.1.50
- DD_AGENT_REMOTE1_SECRET=mysecretkey
ports:
- 3000:3000By default, the controller also watches its own local Docker socket. If you're running the controller as a pure aggregator with no local containers to monitor, set
DD_LOCAL_WATCHER=false to disable the default local watcher.Complete Multi-Host Example
This example shows a controller watching its own containers and connecting to one remote agent. The controller handles notifications (Slack, SMTP, etc.); each agent handles its own container updates.
Controller
services:
drydock:
image: codeswhat/drydock
ports:
- "3000:3000"
depends_on:
socket-proxy:
condition: service_healthy
volumes:
- /path/to/store:/store
environment:
# --- Local watcher (controller's own containers) ---
- DD_WATCHER_LOCAL_HOST=drydock-socket-proxy
- DD_WATCHER_LOCAL_PORT=2375
- DD_WATCHER_LOCAL_WATCHBYDEFAULT=true
# --- Local docker trigger (update controller's own containers) ---
- DD_TRIGGER_DOCKER_LOCAL_PRUNE=true
# --- Remote agent connection ---
- DD_AGENT_REMOTE1_HOST=192.168.1.50
- DD_AGENT_REMOTE1_PORT=3000
- DD_AGENT_REMOTE1_SECRET=mysecretkey
# --- Notifications (run on controller only) ---
- DD_TRIGGER_SMTP_ALERTS_HOST=smtp.example.com
- DD_TRIGGER_SMTP_ALERTS_PORT=587
- DD_TRIGGER_SMTP_ALERTS_USER=user@example.com
- DD_TRIGGER_SMTP_ALERTS_PASS=password
- DD_TRIGGER_SMTP_ALERTS_FROM=drydock@example.com
- DD_TRIGGER_SMTP_ALERTS_TO=admin@example.com
socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- IMAGES=1
- EVENTS=1
- POST=1
- DELETE=1
- NETWORKS=1
- VOLUMES=1
healthcheck:
test: wget --spider http://localhost:2375/version || exit 1
interval: 5s
timeout: 3s
retries: 3
start_period: 5sAgent (on 192.168.1.50)
services:
drydock-socket-proxy:
image: lscr.io/linuxserver/socket-proxy:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- CONTAINERS=1
- IMAGES=1
- EVENTS=1
- POST=1
- DELETE=1
- NETWORKS=1
- VOLUMES=1
healthcheck:
test: wget --spider http://localhost:2375/version || exit 1
interval: 5s
timeout: 3s
retries: 3
start_period: 5s
drydock-agent:
image: codeswhat/drydock
command: --agent
depends_on:
drydock-socket-proxy:
condition: service_healthy
ports:
- "3000:3000"
environment:
# Must match controller's DD_AGENT_REMOTE1_SECRET
- DD_AGENT_SECRET=mysecretkey
# Watcher — discovers containers on this host
- DD_WATCHER_LOCAL_HOST=drydock-socket-proxy
- DD_WATCHER_LOCAL_PORT=2375
# Docker trigger — required to update containers via UI/API
- DD_TRIGGER_DOCKER_LOCAL_PRUNE=trueDo not configure notification triggers (Slack, SMTP, etc.) on agents. Only
docker and dockercompose triggers are supported in agent mode. Notification triggers must be configured on the controller.You do not need to define
DD_TRIGGER_DOCKER_* on the controller for each agent. During the handshake, the controller automatically discovers the agent's triggers and creates internal proxies. The controller only needs its own DD_TRIGGER_DOCKER_* for updating containers on its local host.Features in Agent Mode
- Watchers: Run on the Agent to discover containers.
- Registries: Configured on the Agent to check for updates.
- Triggers:
dockeranddockercomposetriggers are configured and executed on the Agent (allowing update of remote containers). The controller automatically proxies update requests to the correct agent.- Notification triggers (e.g.
smtp,discord) are configured and executed on the Controller.