To allow your Hermes Agent (HA) running inside a Docker container to spin up other Docker containers, you need to implement a mechanism that gives it access to a Docker daemon.
There are two main ways to achieve this, but Docker-out-of-Docker (DooD) is highly recommended for your use case.
Here is the step-by-step guide on how to implement this.
Approach: Docker-out-of-Docker (DooD)
Instead of running a Docker daemon inside your container (which is complex and messy), you mount the host machine's Docker socket into your HA container. When the agent runs a docker command, it actually tells the host machine to spin up a "sibling" container.
Step 1: Mount the Docker Socket¶
When you start your Hermes Agent container, you must bind-mount /var/run/docker.sock.
If using docker run:
docker run -d \ --name hermes-agent \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /path/to/your/host/persistent/volume:/app/workspace \ your-hermes-agent-image
Step 2: Install Docker CLI in your HA Image¶
For your agent to talk to the socket, it needs the Docker CLI installed inside its environment. Update your Hermes Agent Dockerfile to include the Docker CLI:
Assuming an Ubuntu/Debian base image¶
FROM ubuntu:22.04
Install standard dependencies¶
RUN apt-get update && apt-get install -y curl
Install Docker CLI (You don't need the daemon, just the CLI)¶
RUN curl -fsSL https://get.docker.com | sh
Rest of your HA installation...¶
Step 3: Implement the Agent Logic (Using Docker SDK)
If your Hermes Agent is written in Python, NodeJS, or Go, don't use raw shell commands. Use the official Docker SDKs. Because the socket is mounted, the SDK will automatically connect to the host's Docker daemon.
Example in Python (pip install docker):
import docker
client = docker.from_env() # Automatically connects to /var/run/docker.sock
def test_drive_repo(repo_url, workspace_path): # 1. Agent clones the repo into the persistent volume # ... cloning logic ...
# 2. Agent spins up a test container (e.g., a node environment to test a JS repo)
print("Starting test container...")
container = client.containers.run(
"node:18-alpine",
command="npm install && npm test",
# WARNING: When mounting volumes in DooD, you MUST use the HOST machine's path,
# not the path inside the HA container!
volumes={
'/path/to/your/host/persistent/volume/cloned_repo': {
'bind': '/app',
'mode': 'rw'
}
},
working_dir="/app",
detach=True
)
# 3. Wait for the test to finish and get logs
result = container.wait()
logs = container.logs().decode('utf-8')
container.remove()
return logs
Critical Gotcha: Volume Paths
Because you are using the host's Docker daemon, any volume mounts you pass to the new test containers must be referenced by their path on the host machine, NOT the path inside the HA container.
If your host persistent volume is /mnt/data/agent_workspace and it is mounted inside HA as /workspace, when HA tells Docker to spin up a test container, it must tell Docker to mount /mnt/data/agent_workspace. If it asks Docker to mount /workspace, the host Docker daemon won't know what that is.
Security Warning ⚠️
Giving an LLM agent access to /var/run/docker.sock essentially gives it root access to your host machine. If the LLM hallucinates or is prompted maliciously, it can run privileged containers, mount the host's root file system (/), and execute destructive commands.
Mitigations:
- Do not expose this agent to the public internet.
- If possible, set up Docker Rootless mode on your host machine.
- Hardcode the agent's logic to only allow pulling from specific safe images (like node:alpine or python:slim) and prevent it from passing the --privileged flag or mounting arbitrary host directories.
By default, no, most agent or LLM-related Docker images do not include the Docker CLI.
Docker images are typically built to be as lightweight as possible using base images like python:3.10-slim, alpine, or ubuntu. Since running Docker-out-of-Docker is a specialized use case, image creators almost never include the Docker CLI by default to save space and reduce security risks.
How to check if your HA container has it:
You can quickly check if the Docker CLI is already installed inside your currently running Hermes Agent container by running this command on your host machine:
docker exec -it
- If it responds with a version (e.g., Docker version 24.0.5...), you're good to go!
- If it says executable file not found in $PATH or command not found, it is not installed.
What to do if it's missing:
If the CLI isn't there, you shouldn't try to manually install it every time the container starts. Instead, you should create a quick custom Dockerfile that builds on top of your current Hermes Agent image.
Create a Dockerfile in your project folder:
Replace this with the actual name of the image you are currently using¶
FROM your-hermes-agent-image:latest
Switch to root to install packages (if the base image uses a non-root user)¶
USER root
Install Docker CLI (This works for Debian/Ubuntu-based images)¶
RUN apt-get update && \ apt-get install -y ca-certificates curl gnupg && \ install -m 0755 -d /etc/apt/keyrings && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ chmod a+r /etc/apt/keyrings/docker.gpg && \ echo \ "deb [arch="\((dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ "\)(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ tee /etc/apt/sources.list.d/docker.list > /dev/null && \ apt-get update && \ apt-get install -y docker-ce-cli docker-compose-plugin
Switch back to the original user if necessary (e.g., USER appuser)¶
USER appuser¶
(Note: If your base image is Alpine instead of Ubuntu/Debian, the install command is simply RUN apk add --no-cache docker-cli)
Then, build and run this new image:
Build your custom HA image¶
docker build -t custom-hermes-agent .
Run it with the Docker socket mounted¶
docker run -d \ --name hermes-agent \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /your/persistent/volume:/workspace \ custom-hermes-agent
Alternatively, if your agent is strictly using the Docker SDK (like the Python docker library) as shown in the previous response, you actually don't need the Docker CLI installed at all! The SDK communicates directly with the /var/run/docker.sock file via HTTP over Unix sockets, bypassing the need for the docker command-line tool entirely.