diff --git a/.goreleaser.yml b/.goreleaser.yml index fd412fd0e6d..ef98475a207 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -38,6 +38,7 @@ dockers: - 'goreleaser/goreleaser:{{ .Tag }}-amd64' - 'ghcr.io/goreleaser/goreleaser:{{ .Tag }}-amd64' dockerfile: Dockerfile + use_buildx: true binaries: - goreleaser build_flag_templates: @@ -54,6 +55,7 @@ dockers: - 'goreleaser/goreleaser:{{ .Tag }}-arm64' - 'ghcr.io/goreleaser/goreleaser:{{ .Tag }}-arm64' dockerfile: Dockerfile + use_buildx: true binaries: - goreleaser build_flag_templates: diff --git a/internal/pipe/docker/docker.go b/internal/pipe/docker/docker.go index c704f153c3d..3235200a1fb 100644 --- a/internal/pipe/docker/docker.go +++ b/internal/pipe/docker/docker.go @@ -169,7 +169,7 @@ func process(ctx *context.Context, docker config.Docker, bins []*artifact.Artifa return err } - if err := dockerBuild(ctx, tmp, images, buildFlags); err != nil { + if err := dockerBuild(ctx, tmp, images, buildFlags, docker.Buildx); err != nil { return err } @@ -256,10 +256,10 @@ func link(src, dest string) error { }) } -func dockerBuild(ctx *context.Context, root string, images, flags []string) error { - log.WithField("image", images[0]).Info("building docker image") +func dockerBuild(ctx *context.Context, root string, images, flags []string, buildx bool) error { + log.WithField("image", images[0]).WithField("buildx", buildx).Info("building docker image") /* #nosec */ - var cmd = exec.CommandContext(ctx, "docker", buildCommand(images, flags)...) + var cmd = exec.CommandContext(ctx, "docker", buildCommand(buildx, images, flags)...) cmd.Dir = root log.WithField("cmd", cmd.Args).WithField("cwd", cmd.Dir).Debug("running") out, err := cmd.CombinedOutput() @@ -270,8 +270,11 @@ func dockerBuild(ctx *context.Context, root string, images, flags []string) erro return nil } -func buildCommand(images, flags []string) []string { +func buildCommand(buildx bool, images, flags []string) []string { base := []string{"build", "."} + if buildx { + base = []string{"buildx", "build", "."} + } for _, image := range images { base = append(base, "-t", image) } diff --git a/internal/pipe/docker/docker_test.go b/internal/pipe/docker/docker_test.go index 193f79f6c83..80cd7f5a3e1 100644 --- a/internal/pipe/docker/docker_test.go +++ b/internal/pipe/docker/docker_test.go @@ -847,6 +847,7 @@ func TestBuildCommand(t *testing.T) { tests := []struct { name string flags []string + buildx bool expect []string }{ { @@ -864,11 +865,16 @@ func TestBuildCommand(t *testing.T) { flags: []string{"--label=foo", "--build-arg=bar=baz"}, expect: []string{"build", ".", "-t", images[0], "-t", images[1], "--label=foo", "--build-arg=bar=baz"}, }, + { + name: "buildx", + buildx: true, + flags: []string{"--label=foo", "--build-arg=bar=baz"}, + expect: []string{"buildx", "build", ".", "-t", images[0], "-t", images[1], "--label=foo", "--build-arg=bar=baz"}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - command := buildCommand(images, tt.flags) - require.Equal(t, tt.expect, command) + require.Equal(t, tt.expect, buildCommand(tt.buildx, images, tt.flags)) }) } } diff --git a/pkg/config/config.go b/pkg/config/config.go index 85eac5b2f8d..91d11d40e6b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -494,6 +494,7 @@ type Docker struct { SkipPush string `yaml:"skip_push,omitempty"` Files []string `yaml:"extra_files,omitempty"` BuildFlagTemplates []string `yaml:"build_flag_templates,omitempty"` + Buildx bool `yaml:"use_buildx,omitempty"` } // DockerManifest config. diff --git a/www/docs/customization/docker.md b/www/docs/customization/docker.md index 9255492a4c2..649619c5d29 100644 --- a/www/docs/customization/docker.md +++ b/www/docs/customization/docker.md @@ -80,6 +80,11 @@ dockers: # Path to the Dockerfile (from the project root). dockerfile: Dockerfile + # Wether to use `docker buildx build` instead of `docker build`. + # You probably want to set it to true when using flags like `--platform`. + # Defaults to false. + use_buildx: true + # Template of the docker build flags. build_flag_templates: - "--pull" @@ -88,6 +93,7 @@ dockers: - "--label=org.opencontainers.image.revision={{.FullCommit}}" - "--label=org.opencontainers.image.version={{.Version}}" - "--build-arg=FOO={{.Env.Bar}}" + - "--platform=linux/arm64" # If your Dockerfile copies files other than the binary itself, # you should list them here as well. @@ -105,6 +111,9 @@ dockers: !!! 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.