Skip to main content

Docker Manifests

Create multi-architecture Docker manifest lists

Docker manifests combine platform-specific images into a single multi-architecture reference, so users can docker pull and get the right image for their platform automatically.

Classification

Packager + publisher — creates and pushes Docker manifest lists combining multi-arch images. Required: false (optional stage).

Minimal config

crates:
  - name: myapp
    docker_manifests:
      - name_template: "ghcr.io/myorg/myapp:{{ Version }}"
        image_templates:
          - "ghcr.io/myorg/myapp:{{ Version }}-amd64"
          - "ghcr.io/myorg/myapp:{{ Version }}-arm64"

Full config reference

crates:
  - name: myapp
    docker_manifests:
      - name_template: "myorg/myapp:{{ Version }}"  # required; manifest tag (template)
        image_templates:             # required; image references to include (templates)
          - "myorg/myapp:{{ Version }}-amd64"
          - "myorg/myapp:{{ Version }}-arm64"
        create_flags: []             # optional; extra flags for docker manifest create
        push_flags: []               # optional; extra flags for docker manifest push
        skip_push: false             # optional; true | false | "auto"
        id: ""                       # optional; unique identifier
        use: docker                  # optional; docker | podman
        retry:
          attempts: 10               # optional; default 10
          delay: 10s                 # optional; base delay
          max_delay: 5m              # optional; delay cap

Authentication

Docker registry credentials are resolved from the host Docker configuration (~/.docker/config.json). Run docker login before releasing.

Common gotchas

  • Image references must exist: all image_templates must already be pushed before the manifest stage runs. Anodizer cross-checks the list against pushed images and emits "did you mean?" suggestions for near-misses.
  • Digest pinning: anodizer pins image references to their sha256 digest when available. If a digest is missing (e.g., the docker-digests stage was skipped), a tag reference is used with a warning.
  • Retry: manifest push may fail transiently on busy registries. The built-in retry (default 10 attempts, 10s base delay) handles most transient errors.

Republish / update behavior

Not applicable as a config flag — the stage removes any existing manifest before recreating it. Re-running is idempotent (the old manifest is deleted first, preventing stale manifest errors).

Docker manifest config fields

FieldTypeDefaultDescription
name_templatestringManifest name/tag (template)
image_templateslistImage references to include (templates)
create_flagslistnoneExtra flags for docker manifest create (templates)
push_flagslistnoneExtra flags for docker manifest push (templates)
skip_pushstring/boolnoneSkip push: true, false, or "auto" (skip for prereleases)
idstringnoneUnique identifier
usestringdockerBackend: "docker" or "podman". The "podman" backend is Linux-only — see Podman backend for the full caveats and flag-compatibility table.
retryobjectsee belowRetry config for manifest push

Retry config

FieldTypeDefaultDescription
attemptsinteger10Maximum retry attempts
delaystring10sBase delay between retries
max_delaystring5mMaximum delay cap

Behavior

  • Runs during the publishing phase, after images are pushed
  • Removes any existing manifest first (prevents stale manifest errors on re-runs)
  • Pins image references to their sha256 digest when available, falling back to tag references with a warning
  • Provides "did you mean?" suggestions when image references don't match any pushed images
  • Uses exponential backoff retry for transient registry errors
  • Both create_flags and push_flags are template-rendered

Skip push

Control when manifests are pushed:

docker_manifests:
  - name_template: "ghcr.io/myorg/myapp:{{ Version }}"
    image_templates:
      - "ghcr.io/myorg/myapp:{{ Version }}-amd64"
      - "ghcr.io/myorg/myapp:{{ Version }}-arm64"
    skip_push: auto  # skip push for pre-release versions

Full example

crates:
  - name: myapp
    docker_manifests:
      - name_template: "ghcr.io/myorg/myapp:{{ Version }}"
        image_templates:
          - "ghcr.io/myorg/myapp:{{ Version }}-amd64"
          - "ghcr.io/myorg/myapp:{{ Version }}-arm64"
        retry:
          attempts: 5
          delay: "5s"
          max_delay: "2m"
      - name_template: "ghcr.io/myorg/myapp:latest"
        image_templates:
          - "ghcr.io/myorg/myapp:{{ Version }}-amd64"
          - "ghcr.io/myorg/myapp:{{ Version }}-arm64"