container
The container step type builds, pushes, runs, and inspects containers through Docker or Podman, bringing the full container lifecycle into your custom commands and workflows without leaving Atmos.
Set action to choose the operation, then provide the operation's parameters under a single with: block. When action is omitted, Atmos defaults to run.
steps:
- name: build
type: container
action: build
with:
context: .
dockerfile: Dockerfile
tags:
- app:local
- name: smoke
type: container
action: run
with:
image: app:local
command: uname -a
This step type is different from the step-level container field, which runs ordinary type: shell steps inside a shared sandbox.
Fields
action- Operation to perform:
build,push,run, orinspect. Defaults torunwhen omitted. with- Parameters for the chosen
action. The accepted fields depend on the action: see Build, Push, Run, and Inspect. background- For
action: run, start the container detached as a long-running service and continue the workflow. See Background services.
The provider (docker or podman, auto-detected when omitted) and runtime_auto_start (start the Podman machine when no runtime is running) keys stay at the top level of the step, alongside action and with.
Build
action: build builds a container image from a Dockerfile, or from a Docker Bake definition.
steps:
- name: build
type: container
action: build
provider: docker # docker | podman (auto-detected when omitted)
runtime_auto_start: true # start the Podman machine if no runtime is running
with:
engine: buildx # buildx (Docker BuildKit) or omit for the default builder
context: . # build context directory
dockerfile: Dockerfile # path to the Dockerfile
tags:
- app:local
- app:1.0.0
build_args: # values passed as --build-arg
VERSION: 1.0.0
target: runtime # target stage in a multi-stage build
no_cache: false # disable the build cache
pull: true # always pull newer base images
context- Build context directory. Required unless you use
bake. dockerfile- Path to the Dockerfile. Required unless you use
bake. tags- List of image tags to apply.
build_args- Map of build arguments passed as
--build-arg. target- Target stage in a multi-stage Dockerfile.
no_cache- Disable the build cache when set to
true. pull- Always attempt to pull newer base images when set to
true. engine- Build engine:
buildxfor Docker BuildKit, or omit for the default builder. Requiresprovider: docker. bake- Build with Docker Bake instead of a single Dockerfile. See Bake. Requires
provider: docker.
Bake
Set with.bake to build one or more targets from a docker-bake.hcl (or .json) definition:
with:
bake:
file: docker-bake.hcl # primary bake file
files: # additional bake files
- docker-bake.override.hcl
targets: # targets to build (use `target` for a single one)
- api
- worker
set: # overrides in target.key=value form
- api.platform=linux/amd64
vars: # bake variables
VERSION: 1.0.0
load: true # load the result into the local image store
push: false # push the result to the registry
print: false # print the resolved definition and exit
file/files- Primary bake file, and any additional bake files.
target/targets- A single target, or a list of targets to build.
set- List of overrides in
target.key=valueform. vars- Map of bake variables.
load- Load the built image into the local image store.
push- Push the built image to the registry.
print- Print the resolved bake definition and exit without building.
Push
action: push pushes an image and its tags to a registry.
steps:
- name: publish
type: container
action: push
provider: docker
with:
image: app:local # source image to push
tags: # target tags (omit to push all existing tags)
- registry.example.com/app:1.0.0
- registry.example.com/app:latest
image- Source image to push.
tags- Target tags to push. When omitted, Atmos pushes all existing tags for the image.
Run
action: run runs a one-shot container, and is the default when action is omitted.
steps:
- name: smoke
type: container
action: run
provider: docker
env: # environment variables come from the step-level env
LOG_LEVEL: debug
with:
image: app:local # required
command: ./run-tests.sh # required
shell: /bin/sh # shell used to run the command (default /bin/sh)
pull: missing # missing (default) | always | never
workspace: /workspace # where the working directory is mounted (default /workspace)
workspace_read_only: false
cleanup: always # always (default) | on_success | never
user: "1000:1000" # username or UID:GID
run_args:
- --network=host
mounts:
- type: bind
source: ~/.aws
target: /root/.aws
read_only: true
ports:
- host: 8080
container: 80
protocol: tcp
image- Required. Container image to run.
command- Required. Command to run inside the container.
shell- Shell used to execute the command. Defaults to
/bin/sh. pull- Image pull policy:
missing(default),always, ornever. workspace- Container path where the working directory is mounted. Defaults to
/workspace. workspace_read_only- Mounts the workspace read-only when set to
true. cleanup- Cleanup policy:
always(default),on_success, ornever. user- User context for execution. Accepts a username or
UID:GID. run_args- List of additional arguments passed to the runtime's
runcommand. mounts- List of additional volume mounts. See Mounts.
ports- List of published port mappings. See Ports.
runtime- Nested runtime block. Set
runtime.host: trueto grant the container access to the host container runtime (Docker-out-of-Docker) so it can launch sibling containers — Atmos mounts the runtime socket, runs as root, relabels for SELinux, and setsDOCKER_HOST. Opt-in and effectively host-root; works on Docker and rootful podman (on rootless podman the socket is unreachable in-container). May also be set inline on the step asruntime.host.
Environment variables for the container come from the step-level env field, not from a field under with.
action: run also accepts restart and healthcheck under with, mapping onto the Docker Compose shapes. A healthcheck is what gates readiness for background services.
Mounts
with.mounts is a list of mount objects:
with:
image: app:local
command: ls /cache
mounts:
- type: bind # bind (default) | volume | tmpfs
source: ~/.aws # host path (bind) or volume name (volume); `~` expands to home
target: /root/.aws
read_only: true
- type: volume
source: build-cache
target: /cache
- type: tmpfs
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.
read_only- Mounts the source read-only when set to
true. Defaults tofalse.
Ports
with.ports is a list of port mappings:
with:
image: nginx:latest
command: nginx -g 'daemon off;'
ports:
- host: 8080 # host port
container: 80 # container port
protocol: tcp # tcp (default) | udp
host- Host port number to publish.
container- Container port number to map to the host port.
protocol- Port protocol:
tcp(default) orudp.
Inspect
action: inspect displays curated metadata for an image.
steps:
- name: inspect
type: container
action: inspect
provider: docker
with:
image: app:local # image to inspect
image- Required. Image to inspect.
Background services
Set background: true on an action: run step to start a long-running service detached. Atmos starts the container, then continues to the next step instead of blocking on the container's exit. This is how you bring up an emulator, database, or other dependency that later steps need, without dropping into shell scripts and background jobs.
workflows:
e2e:
steps:
- name: emulator
type: container
action: run
background: true
with:
image: localstack/localstack
ports:
- host: 4566
container: 4566
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4566/_localstack/health"]
interval: 5s
retries: 10
start_period: 30s
- name: apply
type: atmos
command: terraform apply vpc -s dev
- type: cancel
for: emulator
Readiness via healthcheck
When a background service declares a healthcheck under with, Atmos blocks until the container reports healthy before running the next step. This reuses the same container health check as container components — no sleep guesses, no readiness-polling scripts. A background service "waits until healthy", never "until exit": a long-running service never exits on its own, so readiness is defined by its health check, not its exit code.
You can also gate readiness explicitly with a wait step ({ type: wait, for: [emulator] }), or wait for every background service at once with wait-all. The ordinary needs field is unchanged and still expresses step ordering.
Teardown
Stop and remove a background service with a cancel step ({ type: cancel, for: emulator }). If you never cancel it explicitly, Atmos automatically tears down all background services when the workflow ends — including on failure — so a crashed workflow does not leave orphaned containers behind.
background- When
trueon anaction: runstep, start the container detached and continue the workflow. The step does not block on the container's exit; readiness is gated by itshealthcheck(or an explicitwaitstep), and teardown happens viacancelor automatically at workflow end.