# Docker Images

GoReleaser can build and push Docker images.
Let's see how it works.

## How it works

You can declare multiple Docker images. They will be matched against
the binaries generated by your `builds` section and packages generated
by your `nfpms` section.

If you have only one `build` setup,
the configuration is as easy as adding the
name of your image to your `.goreleaser.yaml` file:

```yaml
dockers:
  - image_templates:
    - user/repo
```

!!! tip
    The `image_templates` attribute supports templating. Learn more about the [name template engine](/customization/templates/).

You also need to create a `Dockerfile` in your project's root folder:

```dockerfile
FROM scratch
ENTRYPOINT ["/mybin"]
COPY mybin /
```

This configuration will build and push a Docker image named `user/repo:tagname`.

!!! warning
    Note that we are not building any go files in the Docker
    build phase, we are merely copying the binary to a `scratch` image and
    setting up the `entrypoint`.

## Customization

Of course, you can customize a lot of things:

```yaml
# .goreleaser.yaml
dockers:
  # You can have multiple Docker images.
  -
    # ID of the image, needed if you want to filter by it later on (e.g. on custom publishers).
    id: myimg

    # GOOS of the built binaries/packages that should be used.
    goos: linux

    # GOARCH of the built binaries/packages that should be used.
    goarch: amd64

    # GOARM of the built binaries/packages that should be used.
    goarm: ''

    # IDs to filter the binaries/packages.
    ids:
    - mybuild
    - mynfpm

    # Templates of the Docker image names.
    image_templates:
    - "myuser/myimage:latest"
    - "myuser/myimage:{{ .Tag }}"
    - "myuser/myimage:{{ .Tag }}-{{ .Env.GO_VERSION }}"
    - "myuser/myimage:v{{ .Major }}"
    - "gcr.io/myuser/myimage:latest"

    # Skips the docker push.
    # Could be useful if you also do draft releases.
    #
    # If set to auto, the release will not be pushed to the Docker repository
    #  in case there is an indicator of a prerelease in the tag, e.g. v1.0.0-rc1.
    #
    # Defaults to false.
    skip_push: false

    # Path to the Dockerfile (from the project root).
    #
    # Defaults to `Dockerfile`.
    dockerfile: '{{ .Env.DOCKERFILE }}'

    # Set the "backend" for the Docker pipe.
    # Valid options are: docker, buildx, podman, buildpacks
    # podman is a GoReleaser Pro feature and is only available on Linux.
    # Defaults to docker.
    use: docker

    # Template of the docker build flags.
    build_flag_templates:
    - "--pull"
    - "--label=org.opencontainers.image.created={{.Date}}"
    - "--label=org.opencontainers.image.title={{.ProjectName}}"
    - "--label=org.opencontainers.image.revision={{.FullCommit}}"
    - "--label=org.opencontainers.image.version={{.Version}}"
    - "--build-arg=FOO={{.Env.Bar}}"
    - "--platform=linux/arm64"

    # Extra flags to be passed down to the push command.
    # Defaults to empty.
    push_flags:
    - --tls-verify=false

    # If your Dockerfile copies files other than binaries and packages,
    # you should list them here as well.
    # Note that GoReleaser will create the same structure inside a temporary
    # folder, so if you add `foo/bar.json` here, on your Dockerfile you can
    # `COPY foo/bar.json /whatever.json`.
    # Also note that the paths here are relative to the folder in which
    # GoReleaser is being run (usually the repository root folder).
    # This field does not support wildcards, you can add an entire folder here
    # and use wildcards when you `COPY`/`ADD` in your Dockerfile.
    extra_files:
    - config.yml
```

!!! tip
    Learn more about the [name template engine](/customization/templates/).

!!! tip
    You can also create multi-platform images using the [docker_manifests](/customization/docker_manifest/) config.

These settings should allow you to generate multiple Docker images,
for example, using multiple `FROM` statements,
as well as generate one image for each binary in your project or one image with multiple binaries, as well as
install the generated packages instead of copying the binary and configs manually.

## Generic Image Names

Some users might want to keep their image name as generic as possible.
That can be accomplished simply by adding template language in the definition:

```yaml
# .goreleaser.yaml
project: foo
dockers:
  -
    image_templates:
    - "myuser/{{.ProjectName}}"
```

This will build and publish the following images:

- `myuser/foo`

!!! tip
    Learn more about the [name template engine](/customization/templates/).

## Keeping docker images updated for current major

Some users might want to push docker tags `:v1`, `:v1.6`,
`:v1.6.4` and `:latest` when `v1.6.4` (for example) is built. That can be
accomplished by using multiple `image_templates`:

```yaml
# .goreleaser.yaml
dockers:
  -
    image_templates:
    - "myuser/myimage:{{ .Tag }}"
    - "myuser/myimage:v{{ .Major }}"
    - "myuser/myimage:v{{ .Major }}.{{ .Minor }}"
    - "myuser/myimage:latest"
```

This will build and publish the following images:

- `myuser/myimage:v1.6.4`
- `myuser/myimage:v1`
- `myuser/myimage:v1.6`
- `myuser/myimage:latest`

With these settings you can hopefully push several Docker images
with multiple tags.

!!! tip
    Learn more about the [name template engine](/customization/templates/).

## Publishing to multiple docker registries

Some users might want to push images to multiple docker registries. That can be
accomplished by using multiple `image_templates`:

```yaml
# .goreleaser.yaml
dockers:
  -
    image_templates:
    - "docker.io/myuser/myimage:{{ .Tag }}"
    - "docker.io/myuser/myimage:latest"
    - "gcr.io/myuser/myimage:{{ .Tag }}"
    - "gcr.io/myuser/myimage:latest"
```

This will build and publish the following images to `docker.io` and `gcr.io`:

- `myuser/myimage:v1.6.4`
- `myuser/myimage:latest`
- `gcr.io/myuser/myimage:v1.6.4`
- `gcr.io/myuser/myimage:latest`

## Applying Docker build flags

Build flags can be applied using `build_flag_templates`.
The flags must be valid Docker build flags.

```yaml
# .goreleaser.yaml
dockers:
  -
    image_templates:
    - "myuser/myimage"
    build_flag_templates:
    - "--pull"
    - "--label=org.opencontainers.image.created={{.Date}}"
    - "--label=org.opencontainers.image.title={{.ProjectName}}"
    - "--label=org.opencontainers.image.revision={{.FullCommit}}"
    - "--label=org.opencontainers.image.version={{.Version}}"
```

This will execute the following command:

```bash
docker build -t myuser/myimage . \
  --pull \
  --label=org.opencontainers.image.created=2020-01-19T15:58:07Z \
  --label=org.opencontainers.image.title=mybinary \
  --label=org.opencontainers.image.revision=da39a3ee5e6b4b0d3255bfef95601890afd80709 \
  --label=org.opencontainers.image.version=1.6.4
```

!!! tip
    Learn more about the [name template engine](/customization/templates/).

## Podman

!!! success "GoReleaser Pro"
    The podman backend is a [GoReleaser Pro feature](/pro/).

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

```yaml
# .goreleaser.yaml
dockers:
  -
    image_templates:
    - "myuser/myimage"
    use: podman
```

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

## Buildpacks

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

```yaml
# .goreleaser.yaml
dockers:
  -
    image_templates:
    - "myuser/myimage"
    use: buildpacks
```

Also, you can use a custom buildpack on `build_flag_templates` if you want.
By default, `gcr.io/buildpacks/builder:v1` will be used.

```yaml
# .goreleaser.yaml
dockers:
  -
    image_templates:
    - "myuser/myimage"
    use: buildpacks
    build_flag_templates:
    - "--builder=heroku/buildpacks:20"
```
