Skip to content

How to get one multi-platform image with separated dockerfiles? #272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
iav opened this issue May 3, 2020 · 9 comments
Closed

How to get one multi-platform image with separated dockerfiles? #272

iav opened this issue May 3, 2020 · 9 comments

Comments

@iav
Copy link

iav commented May 3, 2020

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?

@tonistiigi
Copy link
Member

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

@iav
Copy link
Author

iav commented May 4, 2020

Thank you!

@iav iav closed this as completed May 4, 2020
@joonas-fi
Copy link

joonas-fi commented Jun 16, 2020

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..

@tonistiigi
Copy link
Member

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.

@tonistiigi
Copy link
Member

tonistiigi commented Jun 16, 2020

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.

@joonas-fi
Copy link

@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.

@tonistiigi
Copy link
Member

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

@joonas-fi
Copy link

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

@njucjc
Copy link

njucjc commented Feb 23, 2024

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.

@tonistiigi How can I obtain information (eg. digest hash value) about the manifest that was pushed using push-by-digest=true? Is looking through log output the only way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants