Container Field
Run all workflow steps in a shared Docker container for consistent execution environment.
Basic Usage
container:
image: python:3.11
steps:
- pip install pandas numpy # Install dependencies
- python process.py # Process dataAll steps run in the same container instance, sharing the filesystem and installed packages.
With Volume Mounts
container:
image: node:24
volumes:
- ./src:/app
- ./data:/data
workingDir: /app
steps:
- npm install # Install dependencies
- npm run build # Build the application
- npm test # Run testsWith Environment Variables
container:
image: postgres:16
env:
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=myapp
steps:
- command: pg_isready -U postgres
retryPolicy:
limit: 10
- psql -U postgres myapp -f schema.sqlPrivate Registry Authentication
# For private images
registryAuths:
ghcr.io:
username: ${GITHUB_USER}
password: ${GITHUB_TOKEN}
container:
image: ghcr.io/myorg/private-app:latest
steps:
- ./appOr use DOCKER_AUTH_CONFIG environment variable (same format as ~/.docker/config.json).
Configuration Options
container:
image: ubuntu:22.04 # Required
pullPolicy: missing # always | missing | never
volumes: # Volume mounts
- /host:/container
env: # Environment variables
- KEY=value
workingDir: /app # Working directory
user: "1000:1000" # User/group
platform: linux/amd64 # Platform
ports: # Port mappings
- "8080:8080"
network: host # Network mode
startup: keepalive # keepalive | entrypoint | command
command: ["sh", "-c", "my-daemon"] # when startup: command
waitFor: running # running | healthy
logPattern: "Ready" # optional regex; wait for log pattern
restartPolicy: unless-stopped # optional Docker restart policy (no|always|unless-stopped)
keepContainer: true # Keep after workflowValidation and Errors
imageis required.volumesmust usesource:target[:ro|rw]format; relative paths are resolved from the DAGworkingDir; invalid formats fail.portsaccept"80","8080:80","127.0.0.1:8080:80"; container port may have/tcp|udp|sctp(default tcp); invalid formats fail.networkacceptsbridge,host,none,container:<name|id>, or a custom network name.restartPolicysupportsno,always, orunless-stopped; other values fail.startupmust be one ofkeepalive(default),entrypoint,command; invalid values fail.waitFormust berunning(default) orhealthy; ifhealthyis chosen but no healthcheck exists, Dagu falls back torunningwith a warning.logPatternmust be a valid regex; readiness waits up to 120s (includinglogPattern), then errors with the last known state.
Key Benefits
- Shared Environment: All steps share the same filesystem and installed dependencies
- Performance: No container startup overhead between steps
- Consistency: Guaranteed same environment for all steps
- Simplicity: No need to configure Docker executor for each step
Execution Model and Entrypoint Behavior
- How it runs: When you set a DAG‑level
container, Dagu starts one long‑lived container for the workflow. By default (startup: keepalive), it runs a lightweight keepalive process (or sleep) so the container stays up. Each step then runs inside that container viadocker exec. - Entrypoint/CMD not used for steps: Because steps are executed with
docker exec, your image’sENTRYPOINTorCMDare not invoked for step commands. Steps run directly in the running container process context. - Implication: If your image’s entrypoint is a dispatcher that expects a subcommand (for example,
my-entrypoint sendConfirmationEmailswhich then callsnpm run sendConfirmationEmails), the step command must invoke that dispatcher explicitly.
Startup Modes
Choose how the DAG‑level container starts:
container:
image: servercontainers/samba:latest
startup: entrypoint # keepalive | entrypoint | command
waitFor: healthy # running | healthy (default running)container:
image: alpine:latest
startup: command
command: ["sh", "-c", "my-daemon --flag"]
restartPolicy: unless-stopped # optionalkeepalive(default): preserves current behavior using an embedded keepalive binary orsh -c 'while true; sleep 86400; done'in DinD.entrypoint: honors the image’sENTRYPOINT/CMDwith no overrides.command: runs a user‑providedcommandarray instead of image defaults.
Readiness before steps run:
waitFor: running(default): continue once the container is running.waitFor: healthy: if image defines a Docker healthcheck, wait for healthy; if not defined, Dagu falls back torunningand logs a warning.logPattern: optional regex; when set, steps start only after this pattern appears in container logs (after the selectedwaitForcondition passes).
Readiness timeout and errors:
- Dagu waits up to 120 seconds for readiness (
running/healthyand anylogPattern). On timeout, it fails the run and reports the mode and last known state (for example,status=exited, exitCode=1).
Examples
Image entrypoint expects a job name as its first argument:
container:
image: myorg/myimage:latest
steps:
# This will NOT pass through the image ENTRYPOINT automatically.
# Explicitly call the entrypoint script or the underlying command.
- my-entrypoint sendConfirmationEmails
# Or call the underlying command directly, if appropriate
- npm run sendConfirmationEmailsIf your step needs a shell to interpret operators (like &&, redirects, or environment expansion), wrap it explicitly:
steps:
- sh -c "npm run prep && npm run sendConfirmationEmails"When to use step-level Docker instead
If you want each step to run via the image’s ENTRYPOINT/CMD (as with a fresh docker run per step), prefer the step‑level Docker executor instead of the DAG‑level container:
steps:
- name: send-confirmation-emails
executor:
type: docker
config:
image: myorg/myimage:latest
autoRemove: true
# Here, Docker will honor ENTRYPOINT/CMD by default
# (or you can override using executor config options)
command: sendConfirmationEmailsNote: When a DAG‑level container: is set, any step using the Docker executor runs inside that shared container via docker exec. In that case, the step‑level Docker config (such as image, container/host/network, and exec) is ignored, and only the step’s command and args are used. To apply step‑specific container settings, remove the DAG‑level container and use the step‑level Docker executor exclusively.
See Also
- Docker Executor - Step-level container execution
- Registry Authentication - Private registry setup
