Skip to content
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

Support multi-platform builds #536

Closed
LuaxY opened this issue Nov 22, 2020 · 14 comments
Closed

Support multi-platform builds #536

LuaxY opened this issue Nov 22, 2020 · 14 comments
Assignees
Labels
type:proposal A proposal for a new feature

Comments

@LuaxY
Copy link

LuaxY commented Nov 22, 2020

Is it possible to support multi-platform (e.g. amd64, arm64, arm v7) image build with docker buildx feature?
With docker command, by using compatible builder, we can now provide --platform flag to specify target platform.

docker [buildx] build --platform linux/amd64,linux/arm64,linux/arm/v7 .

https://docs.docker.com/buildx/working-with-buildx/

@adamgordonbell adamgordonbell added the type:enhancement Small feature requests / adjustments label Nov 24, 2020
@adamgordonbell
Copy link
Contributor

Hi @LuaxY, I believe this should be possible and should be a feature we add. Thank you for submitting it.

@vladaionescu vladaionescu self-assigned this Dec 19, 2020
@vladaionescu vladaionescu added type:proposal A proposal for a new feature and removed type:enhancement Small feature requests / adjustments labels Dec 19, 2020
@vladaionescu
Copy link
Member

Experimental support for multi-platform builds is available in v0.4.3. Here is a simple example: https://github.com/earthly/earthly/blob/main/examples/multiplatform/Earthfile .

If you try this feature out, I'd be very curious about your experience with it - either here or on our Slack.

@LuaxY
Copy link
Author

LuaxY commented Dec 28, 2020

Tested on my project, work perfectly, big thanks!!

Question about local artifacts, example:

main.go

package main

import "fmt"

func main() {
	fmt.Println("test")
}

Earthfile

FROM golang:1.15-alpine
RUN apk --update --no-cache add git
WORKDIR /mailtrap

all:
  BUILD \
    --platform=linux/amd64 \
    --platform=linux/arm64 \
    --platform=linux/arm/v7 \
    --platform=linux/arm/v6 \
    +build

build:
  COPY main.go main.go
  RUN go build -o build/test main.go
  SAVE ARTIFACT build/test AS LOCAL build/test

This will build binary for each platform but also override the local artifcat

+build | Artifact test:master+build/test as local build/test
+build | Artifact test:master+build/test as local build/test
+build | Artifact test:master+build/test as local build/test
+build | Artifact test:master+build/test as local build/test

The final binary is the last platform stage to finish the SAVE ARTIFACT

$ file build/test 
build/test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, [...]

This is the intended behavior? or there is a way to control the artifact name depending the platform?

@vladaionescu
Copy link
Member

Great!

There are four new built-in args available, which you can use for this:

  • TARGETPLATFORM
  • TARGETOS
  • TARGETARCH
  • TARGETVARIANT

You need to predeclare them before using them:

ARG TARGETPLATFORM
RUN echo "The platform is $TARGETPLATFORM"

So in your example, you could have

build:
  COPY main.go main.go
  RUN go build -o build/test main.go
  ARG TARGETPLATFORM
  SAVE ARTIFACT build/test AS LOCAL build/$TARGETPLATFORM/test

@LuaxY
Copy link
Author

LuaxY commented Dec 28, 2020

Perfect thank you!

@vladaionescu vladaionescu changed the title Support multi-platform docker image build with buildx Support multi-platform builds Feb 9, 2021
@bhansconnect
Copy link

Is there a way to remerge a build split by platform instead of propagating it through all dependant builds?
Ex:

get-dep-linux-arm64:
    # Download/setup arm64 version of dep

get-dep-linux-amd64:
    # Download/setup amd64 version of dep

build-app:
    # ideally I would want this to pick the right version of get dep. And just say something like:
    FROM +get-dep

Instead, i believe with the current setup, i would need to make build-app-linux-arm64 and build-app-linux-amd64

@vladaionescu
Copy link
Member

You should have get-dep defined in a single target. You can use builtin args like TARGETPLATFORM if you need to do a bash conditional. In the future we plan on having a built-in IF command.

After that, you can reference FROM +get-dep and it'll use the same platform build-app is being built as.

@bhansconnect
Copy link

Yeah, I saw the if proposal, it would definitely solve my issue.

Frankly all I need to do to solve my specific issue is to map targetplatform.
Essentially:
amd64 -> x86_64
arm64 -> aarch64
etc
And then I would be able to just directly download the file and extract the file.
Probably will just make a small bash script with that if to deal with the conversion.

@n-rodriguez
Copy link

n-rodriguez commented Oct 19, 2021

Hi there! Do you plans for the --platform CLI option?

For now it says :

earthly --platform=linux/amd64 --platform=linux/arm64 --build-arg DISTRO_NAME=bullseye +build 
           buildkitd | Found buildkit daemon as docker container (earthly-buildkitd)
Error: multi-platform builds are not yet supported on the command line. You may, however, create a target with the instruction BUILD --plaform ... --platform ... +build

An Earthfile with BUILD is not really an option since it must be called dynamically.

Thank you!

@vladaionescu
Copy link
Member

No plans yet.. wondering what you mean by "dynamically". I believe the Earthfile should have enough flexibility in terms of parameters / IF,ELSE etc. Wondering if you have a use-case where the Earthfile language isn't enough.

@n-rodriguez
Copy link

n-rodriguez commented Oct 19, 2021

wondering what you mean by "dynamically"

From a ruby script :earthly --platform ... +build

The arch list is stored in a YAML file read by Ruby which calls earthly.

Putting the arch list in Earthfile would defeat the purpose of the whole thing.

@n-rodriguez
Copy link

Wondering if you have a use-case where the Earthfile language isn't enough.

The issue is not the Earthfile language but the CLI.

@n-rodriguez
Copy link

wondering what you mean by "dynamically"

read it as generic

@vladaionescu
Copy link
Member

Got it - yeah makes sense. We should support that. Mind opening a new issue about it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:proposal A proposal for a new feature
Projects
No open projects
Development

No branches or pull requests

6 participants