Container Components
Container components are stack-scoped, persistent containers. One component is one service. Atmos owns the image artifact (build/push/pull) and an optional long-running named container lifecycle, discovered by labels derived from the canonical component instance address — not from local state files. You declare them with the same stack-based configuration used for Terraform, Helmfile, Packer, and Ansible.
For the conceptual overview and command walkthrough, see Using Containers. This page is the stack-manifest configuration reference.
Available Configuration Sections
Container components are declared under components.container and use first-class sections (siblings of metadata — not nested under vars):
image- The image reference to run (and the default push/pull target). May be set directly or produced by
build. build- How to build the image —
context,dockerfile,tags,build_args,target,no_cache,pull, and more. Reuses the same shape as thetype: containerworkflow step. run- How to run the long-lived container —
command,ports,mounts,user,run_args,pull,restart, andhealthcheck. env- Container application environment, resolved with secrets. Injected into the running container — not read from
run. composition- Optional composition membership — groups this service into a larger system.
metadata- Component behavior and inheritance (e.g.
metadata.type: abstractfor catalog base components). hooks- Lifecycle event handlers.
Component Structure
A typical container component configuration:
components:
container:
api:
composition: storefront # composition membership (optional)
image: localhost:5001/api:latest
build: # build the image
context: app
dockerfile: Dockerfile
tags:
- localhost:5001/api:latest
run: # run configuration
command: ./api
ports:
- host: 8080
container: 80
mounts:
- source: .
target: /workspace
restart:
policy: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 30s
retries: 3
env: # component env (resolved with secrets)
PORT: "8080"
Inheritance (metadata.inherits), catalogs, mixins, and deep-merge work exactly like other component kinds — define an abstract base component with shared run/build defaults and inherit it.
Component-Type Defaults
Define defaults for all container components:
# Apply to all container components
container:
run:
restart:
policy: unless-stopped
# Individual components
components:
container:
api:
image: localhost:5001/api:latest
Complete Example
Running Container Commands
Atmos provides commands that wrap the container lifecycle:
atmos container build api -s dev # build the image from `build`
atmos container up api -s dev # create/start the long-running container (build-on-missing)
atmos container list # all container components + running state
atmos container ps api -s dev # show running state
atmos container logs api -s dev # stream logs
atmos container exec api -s dev -- sh # run a command inside the container
atmos container down api -s dev # stop + rm
Each instance is named and labeled from its canonical address <stack>/container/<component> (e.g., atmos-dev-container-api), so lifecycle commands discover it by label — there are no local state files.
Containers in the same stack automatically join a shared network and can resolve each other by a <stack>-<component> DNS alias, with no configuration required — see Networking.
CI Reporting
When CI is enabled, atmos container build and atmos container push write a summary for each image to the job summary: the tag, digest, image ID, runtime settings, environment variables, labels, and layers. The job summary always keeps the full report, and every pushed reference gets its own section.
Pull request comments
The same summary can also be posted as a pull request comment. Atmos posts a comment only when all of these are true:
ci.enabledandci.summary.enabledare on, and Atmos runs under a detected CI provider, so the summary reached the provider.ci.comments.enabledistrue. Comments are off by default because they write to the pull request.- A pull request number is known. When none is known, for example on a push to a branch, the comment is posted as a commit comment on the run's commit instead.
- The job token can write comments. On GitHub Actions, grant
pull-requests: write, andcontents: writefor commit comments.
Atmos keeps one comment per image, not one per tag. The comment key is container:image:<registry/repository> with the tag and digest removed, so ghcr.io/acme/api:sha-1a2b3c and ghcr.io/acme/api:latest update the same comment. A build or push replaces the body in place, and a push of several tags lists every reference pushed in that run. Images with different repositories, for example one pushed to two registries, get separate comments.
GitHub rejects comment bodies over 65,536 characters. Atmos truncates the comment body at 65,000 characters and ends it with a note that points to the job summary, which keeps the full report. A comment that cannot be posted logs a warning that names the image and never fails the build or push.
When comments are off, Atmos does not post a comment and does not print a preview of one to the log. Outside CI, the summary is rendered locally as before.
To change the Markdown, point ci.templates.container.image at a template file under ci.templates.base_path:
See CI templates for the template syntax and the data available to the image template.
Related
- Using Containers — Conceptual overview and command walkthrough
- atmos container — Command reference
- Emulator Components — Built on the same container lifecycle
- Component Types Overview
- Configure Environment