---
title: "Docker Manifests (deprecated)"
weight: 180
---

> [Phasing out](/resources/deprecations/#dockers) in v2.12.
> [Docker Images v2](/customization/package/dockers_v2/) is preferred instead.

GoReleaser can also create and push Docker multi-platform images using the
`docker manifest` tool.

For it to work, it needs to be enabled in the
[client's configuration](https://github.com/docker/cli/blob/master/experimental/README.md).

Please make sure `docker manifest` works before opening issues.

Notice that if you have something in the `docker_manifests` section in your
config file, GoReleaser will add the manifest's to the release notes instead of
the Docker images names.

> [!WARNING]
> Notice that the images used in the manifest **need to be pushed** for this
> to work. This is a limitation of how `docker manifest create` works. For
> more info, check
> [this issue](https://github.com/goreleaser/goreleaser/issues/2606).

## Customization

You can create several manifests in a single GoReleaser run, here are all the
options available:

```yaml {filename=".goreleaser.yaml"}
docker_manifests:
  # You can have multiple Docker manifests.
  - # ID of the manifest, needed if you want to filter by it later on (e.g. on
    # custom publishers).
    id: myimg

    # Name for the manifest.
    #
    # Templates: allowed.
    name_template: "foo/bar:{{ .Version }}"

    # Image name to be added to this manifest.
    #
    # Templates: allowed.
    image_templates:
      - "foo/bar:{{ .Version }}-amd64"
      - "foo/bar:{{ .Version }}-arm64v8"

    # Extra flags to be passed down to the manifest create command.
    create_flags:
      - --insecure

    # Extra flags to be passed down to the manifest push command.
    push_flags:
      - --insecure

    # Retry configuration for manifest operations.
    #
    # {{< g_inline_version "v2.12" >}}
    retry:
      # Attempts of retry.
      #
      # Default: 10.
      attempts: 5

      # Delay between retry attempts.
      #
      # Default: 10s.
      delay: 5s

      # Maximum delay between retry attempts.
      #
      # Default: 5m.
      max_delay: 2m

    # Skips the Docker manifest.
    # If you set this to `false` or `auto` on your source Docker configuration,
    #  you'll probably want to do the same here.
    #
    # If set to `auto`, the manifest will not be created in case there is an
    #  indicator of a prerelease in the tag, e.g. v1.0.0-rc1.
    #
    # Templates: allowed.
    skip_push: false

    # Set the "backend" for the Docker manifest pipe.
    # Valid options are: docker, podman
    #
    # Relevant notes:
    # 1. podman is a GoReleaser Pro feature and is only available on Linux;
    # 2. if you set podman here, the respective docker configuration need to use
    #     podman too.
    #
    # Default: 'docker'.
    use: docker
```

{{< g_templates >}}

## How it works

We basically build and push our images as usual, but we also add a new
section to our configuration defining, which images are part of which manifests.

GoReleaser will create and publish the manifest in its publishing phase.

> [!WARNING]
> Unfortunately, the manifest tool needs the images to be pushed to create
> the manifest, that's why we both create and push it in the publishing phase.

## Example config

In this example we will use Docker's `--platform` option to specify the target platform.
This way we can use the same `Dockerfile` for both the `amd64`, and the `arm64`
images (and possibly others):

```dockerfile
# Dockerfile
FROM alpine
ENTRYPOINT ["/usr/bin/mybin"]
COPY mybin /usr/bin/mybin
```

Then, on our GoReleaser configuration file, we need to define both the
`dockers`, and the `docker_manifests` section:

```yaml {filename=".goreleaser.yaml"}
builds:
  - env:
      - CGO_ENABLED=0
    binary: mybin
    goos:
      - linux
    goarch:
      - amd64
      - arm64
dockers:
  - image_templates:
      - "foo/bar:{{ .Version }}-amd64"
    use: buildx
    dockerfile: Dockerfile
    build_flag_templates:
      - "--platform=linux/amd64"
  - image_templates:
      - "foo/bar:{{ .Version }}-arm64v8"
    use: buildx
    goarch: arm64
    dockerfile: Dockerfile
    build_flag_templates:
      - "--platform=linux/arm64/v8"
docker_manifests:
  - name_template: "foo/bar:{{ .Version }}"
    image_templates:
      - "foo/bar:{{ .Version }}-amd64"
      - "foo/bar:{{ .Version }}-arm64v8"
```

> [!WARNING]
> Notice that `--platform` needs to be in the Docker platform format, not Go's.

That config will build the 2 Docker images defined, as well as the manifest,
and push everything to Docker Hub.

## Using Podman

{{< g_featpro >}}

You can use [`podman`](https://podman.io) instead of `docker` by setting `use`
to `podman` on your configuration:

```yaml {filename=".goreleaser.yaml"}
docker_manifests:
  - name_template: "foo/bar:{{ .Version }}"
    image_templates:
      - "foo/bar:{{ .Version }}-amd64"
      - "foo/bar:{{ .Version }}-arm64v8"
    use: podman
```

Note that GoReleaser will not install Podman for you, nor change any of its
configuration.
