openfaas / faas-cli

Official CLI for OpenFaaS
https://www.openfaas.com/
Other
798 stars 224 forks source link

[Feature] Add Docker buildx multi-arch support #770

Open mrsimpson opened 4 years ago

mrsimpson commented 4 years ago

In order to support the packaging of a function multi-platform docker images, the FaaS CLI build command needs to provide new options to select the target platforms

Expected Behaviour

Ability to pass a list of target platforms to the docker build.

Current Behaviour

There's no option to pass this parameter.

Possible Solution

Add a new parameter --platform to the build command. The supported platforms (e. g. linux/amd64,linux/arm/v7) should be included in the faas-cli build --help Experimental docker features (buildx/buildkit) should be enabled implicitly.

Context

While building multi-platform in a CI, the build needed to be triggered outside the faas-cli using native docker commands.

alexellis commented 4 years ago

@utsavanand2 just asked me about this issue.

--platform relies on Buildkit being used (buildx is an interface to buildkit AFAIK) - with the tooling - we are trying not to couple tightly to container builders.

For instance, faas-cli build --shrinkwrap produces a generic build context that can be built by any container builder, but additional metadata like "platform" is not going to be supported.

I am also not sure whether Kaniko or other builds support this notion as of yet, it certainly won't work with openfaas cloud which uses the above shrink-wrap approach.

We recently added the ability to pass a build-arg - can you pass your platform value that way, or via an ENV-var? - this can be passed via CLI args and via stack.yml

To enable Buildkit, you can run DOCKER_BUILDKIT=1 faas-cli build for instance.

alexellis commented 4 years ago

/set title: [Feature] Add Docker buildx multi-arch support

alexellis commented 4 years ago

I spent some time prototyping this. There is a bit of a problem at present with the way that buildx vs docker works.

buildx for Multiplatform can't build to the local library, so must push to a registry to then be pulled back and used again. This is due to multi-arch manifests. See tweet

I prototyped this and hacked the faas-cli build command to do a push for three architectures, it worked as expected, however it ties builds to pushes, which breaks our concept of build/push/deploy (or "up")

I would welcome suggestions on how we move this forward from a user-experience point of view.

alexellis commented 4 years ago

As a follow-up, buildx will need to be used to build each image separately, passing one architecture / platform at a time. At the push step, we will need to push each image, and then create a manifest against the target repository.

colearendt commented 2 years ago

This feature is important for M1 mac users who are deploying to non-arm architectures. In this case, it is important to build with the --platform linux/amd64 flag.

If the fix is any easier in the short term, I would welcome a single-valued --platform argument (i.e. can only build to one architecture at a time) or a generic --builder-arg command that passes arguments to the builder CLI itself (as opposed to build ARGs that are passed to the Dockerfile). This way the user has to manage the ergonomics themselves.

EDIT: I also think it would be nice to be able to set this in the yaml or env vars if possible too. 🤷 (Especially if there is a dedicated --platform argument)

crispyricepc commented 1 year ago

M1 Mac user here, was looking for a solution. At the moment my workaround is to set the DOCKER_DEFAULT_PLATFORM variable to linux/amd64. For example:

DOCKER_DEFAULT_PLATFORM=linux/amd64 faas-cli -f <cfg.yml> up
alexellis commented 1 year ago

@crispyricepc you should just be able to write the following?

faas-cli publish --platform linux/amd64

And to be clear, you want to cross-compile to amd64 from your M1 right?