container
With a container defined on a workflow, Atmos runs your type: shell steps inside a single persistent container for the duration of the workflow run, instead of on the host. Every step shares the same image, tools, and environment, so tools you install in an early step stay available to later steps. It uses the same container runtime that powers the type: container step.
The example below uses every field. See Mounts, Ports, and Per-step overrides for the nested definitions.
workflows:
test:
working_directory: .
container:
image: alpine:latest # required
shell: /bin/sh # shell used to run each command (default /bin/sh)
provider: docker # docker | podman (auto-detected when omitted)
runtime_auto_start: true # start the Podman machine if no runtime is running
pull: missing # missing (default) | always | never
workspace: /workspace # where working_directory is mounted (default /workspace)
workspace_read_only: false # mount the workspace read-only
cleanup: always # always (default) | on_success | never
user: "1000:1000" # username or UID:GID
run_args: # extra args passed to `docker run` / `podman run`
- --network=host
env: # environment defaults for every step
TOOL_CACHE: /tmp/tools
mounts: # additional volume mounts (see Mounts below)
- type: bind
source: ~/.aws
target: /root/.aws
read_only: true
ports: # published ports (see Ports below)
- host: 8080
container: 80
protocol: tcp
steps:
- name: dependencies
type: shell
command: apk add --no-cache jq
- name: test
type: shell
working_directory: services/api
command: jq --version
- name: on-host
type: shell
command: echo "this step runs on the host"
container: false # opt a single step out of the sandbox
This field is different from steps[].type: container, which is a step type for container build, push, run, and inspect operations.
Fields
image- Container image for the workflow sandbox. Required when
containeris configured. shell- Shell used to execute commands inside the container. Defaults to
/bin/sh. provider- Container runtime provider:
dockerorpodman. When omitted, Atmos auto-detects Docker, then Podman. runtime_auto_start- Allows Atmos to attempt runtime recovery, such as starting a Podman machine, instead of failing when no runtime is running.
pull- Image pull policy:
missing(default),always, ornever. workspace- Container path where the workflow working directory is mounted. Defaults to
/workspace. workspace_read_only- Mounts the workflow workspace read-only when set to
true. cleanup- Sandbox cleanup policy:
always(default),on_success, ornever. user- User context for container execution. Accepts a username or
UID:GIDformat. run_args- List of additional arguments passed to the container runtime's
runcommand, such as--network=host. env- Map of environment variables passed to every command in the sandbox.
mounts- List of additional volume mounts. See Mounts.
ports- List of published port mappings. See Ports.
Mounts
mounts is a list of mount objects. Use it to share host paths, named volumes, or in-memory tmpfs filesystems into the sandbox:
container:
image: alpine:latest
mounts:
- type: bind # mount a host path
source: ~/.aws # `~` expands to the host home directory
target: /root/.aws
read_only: true
- type: volume # mount a named volume
source: build-cache
target: /cache
- type: tmpfs # mount an in-memory filesystem
target: /tmp/scratch
type- Mount type:
bind(default),volume, ortmpfs. source- Host path for
bindmounts or the volume name forvolumemounts. Not used fortmpfs.~expands to the host home directory. target- Required. Path inside the container where the mount is attached.
read_only- Mounts the source read-only when set to
true. Defaults tofalse.
Ports
ports is a list of port mappings that publish container ports to the host:
container:
image: nginx:latest
ports:
- host: 8080 # port on the host
container: 80 # port inside the container
protocol: tcp # tcp (default) or udp
- host: 5353
container: 53
protocol: udp
host- Host port number to publish.
container- Container port number to map to the host port.
protocol- Port protocol:
tcp(default) orudp.
Per-step overrides
Every step inherits the workflow sandbox by default. A step can nest its own container field to override the inherited settings, or set container: false to run on the host:
workflows:
build:
container:
image: golang:1.26
env:
CGO_ENABLED: "0"
steps:
- name: compile
type: shell
command: go build ./... # runs in the golang:1.26 sandbox
- name: bundle
type: shell
command: npm run bundle
container: # override just this step
image: node:22
env:
NODE_ENV: production
- name: release
type: shell
command: ./scripts/release.sh
container: false # run on the host
A per-step container is merged onto the workflow sandbox rather than replacing it wholesale:
- Scalar fields you set (
image,shell,provider,pull,workspace,cleanup,user) overlay the inherited value; unset fields keep the workflow value. In the example above,bundlerunsnode:22but still inheritscleanupandproviderfrom the workflow. runtime_auto_startandworkspace_read_onlyare enabled if either the workflow or the step sets them.mounts,ports,env, andrun_argsreplace the inherited list when the step provides a non-empty value, so list the full set you want for that step.