Buildx: How to get one multi-platform image with separated dockerfiles?

Created on 3 May 2020  路  8Comments  路  Source: docker/buildx

I need to use separate dockerfiles for different platforms, but want to see a result as one multi-platform image.
I try to use bake file:

cat bake.hcl
variable "V" {
    default = "latest"
}

group "default" {
    targets = ["inadyn-x64", "inadyn-arm"]
}

target "inadyn-x64" {
    dockerfile = "Dockerfile"
    context = "."
    platforms = ["linux/amd64"]
    tags = ["docker.io/shtripok/inadyn:${V}"]
}

target "inadyn-arm" {
    inherits = ["inadyn-x64"]
    dockerfile = "Dockerfile.arm"
    platforms = [ "linux/arm64", "linux/arm/v7" ]
}

but seems it first push x64 single platform image, then overwrite it with two-platform arm image.

Is it possible to get one tri-platform image with 2 different dockerfile?

All 8 comments

You can't do this with a single build command invocation, but you can join the separate images together with https://github.com/docker/buildx#buildx-imagetools-create-options-source-source

Note that if you would use a single Dockerfile, different platforms can point to different stages in that Dockerfile, eg. like https://github.com/moby/buildkit/blob/99b2abfb76607caa04418c1b097709b3df829287/Dockerfile#L216

Thank you!

You can't do this with a single build command invocation, but you can join the separate images together with https://github.com/docker/buildx#buildx-imagetools-create-options-source-source

@tonistiigi: is this only for images that already exist at a remote registry (like DockerHub)? I'm having trouble coming up with a command that takes local images I have and produce a multi-arch manifest.

I would like to not end up with joonas/myapp:<version>-amd64, joonas/myapp:<version>-armv7 ... tags, like the buildx build ... command supports (push all as only one tag), but the build command has too much assumptions built around the automation so I can't use it. Specifically, I have ready-made binaries which I would just like to plop inside each arch-specific image - basically I would want:

Dockerfile-amd64

FROM alpine

ADD rel/myapp_amd64 /myapp

Dockerfile-armv7

FROM alpine

ADD rel/myapp_armv7 /myapp

The only way I can get buildx to support my use case is to have instead of this ..:

rel/myapp_amd64
rel/myapp_armv7

.. have this:

rel/linux/amd64
rel/linux/arm/v7

And have a single Dockerfile like this:

FROM alpine

ARG TARGETPLATFORM

ADD "$TARGETPLATFORM" /myapp

While this would work, it seems like a hack and should I ever need to customize something by architecture, I'd need separate Dockerfiles anyway..

buildx imagetools commands only work on the images in a registry and they also already need to be on the same repository scope. If you don't want to tag the images that will be merged later you can set push-by-digest=true in --output options.

The only way I can get buildx to support my use case is to have instead of this

You can use $TARGETARCH$TARGETVARIANT for the naming you need.

@tonistiigi wow, those were some really good tips, thanks! Awesome. Short, to the point and exactly what I asked. 馃憦

It was somewhat hard even finding the TARGETPLATFORM automatic arg via web searches, let's hope the search results improve and TARGETARCH & TARGETVARIANT are more easily findable, just now I found https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope :)

One more question, it's great that push-by-digest=true is available. Do you know if vanilla Docker supports that?

"Docker push by digest" search term yields practically nothing, and https://docs.docker.com/engine/reference/commandline/push/ makes it seem it's not available since the doc page for pull lists digest as optional.

One more question, it's great that push-by-digest=true is available. Do you know if vanilla Docker supports that?

No, docker push does not support that afaik, so push needs to be performed by buildkit (with buildx this means using container or k8s driver). Some docs in https://github.com/moby/buildkit#imageregistry

@tonistiigi ok, thank you so much for all your informative answers!

Was this page helpful?
0 / 5 - 0 ratings