Skip to main content

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 container is configured.
shell
Shell used to execute commands inside the container. Defaults to /bin/sh.
provider
Container runtime provider: docker or podman. 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, or never.
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, or never.
user
User context for container execution. Accepts a username or UID:GID format.
run_args
List of additional arguments passed to the container runtime's run command, 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, or tmpfs.
source
Host path for bind mounts or the volume name for volume mounts. Not used for tmpfs. ~ 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 to false.

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) or udp.

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, bundle runs node:22 but still inherits cleanup and provider from the workflow.
  • runtime_auto_start and workspace_read_only are enabled if either the workflow or the step sets them.
  • mounts, ports, env, and run_args replace the inherited list when the step provides a non-empty value, so list the full set you want for that step.