Docker sandbox for harness.run
Run agent harnesses inside a Docker sandbox.
Dagu can start a Docker container for an entire DAG run or for one harness.run step. The examples below keep the boundary visible: filesystem mounts, environment variables, network access, and the provider binary all come from the container configuration.
type: graph
container:
image: alpine:3.20
pull_policy: missing
working_dir: /workspace
volumes:
- .:/workspace
env:
- SMOKE_TOKEN=container-env-ok
harnesses:
shell:
binary: sh
prefix_args:
- -c
prompt_mode: arg
steps:
- id: write_file
run: echo "from command step" > shared.txt
- id: read_file
action: harness.run
with:
provider: shell
prompt: |
set -eu
cat shared.txt
echo "SMOKE_TOKEN=$SMOKE_TOKEN"
cat /etc/alpine-releaseRoot-level container shares one filesystem across command and harness steps.
Step-level container isolates one harness attempt with its own image and mounts.
Docker is the default runtime when DAGU_CONTAINER_RUNTIME is unset.
The Alpine examples verify the container path without calling a model provider.
Container scope
Use root-level container when command steps and harness steps should share files and tools. Use step-level container when only one agent attempt should receive a runner image, workspace mount, and credential.
- Root-level container applies to inherited command steps and CLI-based harness.run steps.
- A step-level container overrides the root-level container for that step.
- Named existing containers can be attached, but image mode is clearer for reproducible agent runners.
Agent network access
Codex, Claude Code, OpenCode, and similar hosted agent CLIs usually need outbound network access to reach their provider APIs. Dagu sets the container network mode; allow or deny egress with Docker, Podman, firewall, or proxy configuration outside Dagu.
- Leave container.network unset for default Docker networking, or set a custom network that has the required egress.
- Use Docker or Podman networks, firewall rules, or proxy environment variables for allow/deny policy.
- `network: none` is only for commands that never call external services; it is not a useful hosted-agent example.
Runtime environment
Set the container runtime on the Dagu process that executes the run: server, scheduler, worker, or CLI. Docker is selected by default, and standard Docker variables such as DOCKER_HOST still apply.
- Use DAGU_CONTAINER_RUNTIME=docker only when you want to be explicit.
- If Dagu itself runs in Docker, mount the Docker socket only into trusted Dagu workers.
- The agent runner container does not need the Docker socket unless the agent itself should manage containers.
Credentials
Credentials are not implicit. Add them with container.env or mount the credential directory the provider actually reads. Root-level credentials are visible to every inherited step in the shared container.
Provider examples
Docker sandbox for harness.run
Build a Codex runner from the OpenAI base image and reuse CODEX_HOME or CODEX_API_KEY.
Claude Code in DockerInstall Claude Code in a Node image and pass Anthropic credentials into one step.
OpenCode in DockerInstall OpenCode, mount its auth directory, and run opencode through harness.run.
Custom CLI in DockerDefine a custom provider for an internal CLI or wrapper script.