-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
(assets): allow user to pass platform option to Docker builds #12472
Comments
Any progress on this? |
We are not actively working on this. Pull requests are more than welcome. @relm923 I see you closed your pull request. Would you be interested in continuing to work on this? I am happy to help out with the review (sorry you didn't get a response for a while). |
@eladb I'm happy to continue working on it. I closed the first PR because it appears the CodeBuild environment does not have experimental features ( |
Hello all, really looking forward for this feature. But a question from me, is Here is what I am talking about, and mind you I am running this on my M1 Macbook, with the following Docker version installed:
I build my docker image with the docker build --platform linux/amd64 . This provides me with an image that is built with the correct architecture:
I can clearly see that this image is of |
Good catch, @darko-mesaros! Did you happen to check if it works in the same way on the latest x86 Docker for Mac? — Just |
It indeed did work. I was able to build the image on an Intel Macbook by using the EDIT: Just tried it, an arm64 image built on the Intel Mac works when I run it on the M1 mac. 👏 |
Did hit same problem building layer for lambda.
So do we plan to add something like "platform" option ??
Running docker manually with --platform linux/amd64 did work ok.
|
It should be good to go... |
Fixes #12472 Adds an option to specify the platform for the `docker build` command would allow users to build for other targets (e.g. Apple M1 users can build for amd64 architectures) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
Hi @alukach It seems the Looks like we need another PR, no? |
I noticed the same, and I think it is because the |
Just a note for people with M1 chip. Docker supports DOCKER_DEFAULT_PLATFORM='linux/amd64' env variable now. |
Glad to see the renewed interest. Yes, I do believe that the PR I originally put together affected the wrong part of the codebase 🤦 . I am still unable to build any assets for ECR with my M1 machine. I previously did some initial research into this and got a bit lost trying to understand how/where the CDK ECR code actually instructs Docker to build the image. Here are some notes (largely written out for myself while I try to work this through) of what I think may be the next steps:
I'm willing to put some time into creating another PR, however having some others pair with me on understanding how the bundling actually works would be helpful. |
Docker image assets are built here aws-cdk/packages/cdk-assets/lib/private/docker.ts Lines 49 to 59 in ef12609
|
One solution that I found (after much head banging 🙉 ) is to put FROM --platform=linux/amd64 someBaseImage:someVersion
# ... moar cool docker stuff here 🐳 You could also use a build arg to specify an arbitrary value for platform or create different target images for different platforms you need to support. I hope this helps :) |
Now that Lambda released support for |
I am interested to explore this. I think we need pass the aws-cdk/packages/cdk-assets/lib/private/handlers/container-images.ts Lines 122 to 129 in c2852c9
|
This is the way I also choose, but it annoys me as I'm using the same multi-stage Dockerfile for local environment (some developers are using the M1 chip, some other are using an x86 platform). This means every developer with a M1 chip locally needs to remember to manually edit its Dockerfile before a build. Specify the platform in CDK would be the perfect solution, something like these: # Using build_args (currently ignored)
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
container_name="mytask",
container_port=5000,
image=ecs.ContainerImage.from_asset('.',
build_args={"--platform": "linux/amd64"},
target="production"))
# Using a dedicated argument (currently not available)
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
container_name="mytask",
container_port=5000,
image=ecs.ContainerImage.from_asset('.',
platform="linux/amd64",
target="production")) |
I am working on the PR now. Any comments are appreciated. |
I just noticed an important issue I was using the same Dockerfile with the same base image, which supports multi-arch. When I first This could be a major issue if users are using the same base image for different architectures. Any comments? UPDATEThe
|
I don't have the same behavior. For me changing the platform correctly rebuilds. I'm on |
Now I understand why you see that happening on Linux ( If you run first:
and then:
You'll get two different images with two different architectures 🎉 I think it would be relatively safe to enable the BuildKit when we set the platform. Some references from Docker issues:
The latter issue explains the four(4) different ways to build container images with Docker 😄 and also reveals that they're planning to make |
Thanks for confirming @jogold 🙌🏼 The reason why I was a little bit unsure about this is that I run Docker with all experimental features enabled, so it doesn't always match with the experience most people see. |
So, two things would be ideal, but each is also very valuable:
|
For the use case of building an x86 lambda layer on a M1 Mac, after fighting with it for quite a while I realized there was a completely trivial solution... I just changed
to
|
@pahud I am assigning this to you to follow up. |
This issue has been renamed/repurposed a few times, but I think the CDK API should support passing any arguments to In our case, we need support for adding the We use CDK to build and deploy an ARM64 image on an x86-based (i.e. AMD64) Linux EC2 instance. Only Docker desktop offers multi-platform builds out of the box, so we had to install it, as per Docker's guide. We make BUT
Because CDK
Workarounds like @nathanpeck's #12472 (comment) are not an option for us, since we need to be able to synthesize our CDK stack without building all the Docker images (which requires long compilation etc). Our current workaround is to rename the #!/usr/bin/env bash
if [ "$1" = "build" ]; then
echo "Adding --load param to docker build command"
docker_real build --load "${@:2}"
else
docker_real "$@"
fi But this is obviously a hack and the proper solution would be for CDK Finally, as noted above by @nikovirtala, in #12472 (comment), Docker recently merged a PR to make |
If you're building docker images for Lambda functions, you can do FROM public.ecr.aws/lambda/python:3.8-x86_64 instead of FROM public.ecr.aws/lambda/python:3.8, and it should enforce the x86_64 architecture even on an M1 mac. Docker seems to be smart enough to build for x86_64 if the base image is x86_64, but the alias public.ecr.aws/lambda/python:3.8 is not explicit about it so apparently Docker is downloading public.ecr.aws/lambda/python:3.8-arm64 by default on my M1 mac |
…ker images (#20439) This PR adds support for specifying the desired build platform when building docker images (ie: build an arm64 image on an amd64/x86_64 host). Closes #12472 This PR does NOT touch Lambda builders, only ECR assets. #16770 attempted to implement support for ECR and Lambda but was abandoned. Meanwhile #16858 implemented lambda platform support. This implements the ECR side I have run `yarn integ` ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
Based on [this](#16770) PR Add the missing part to add platform support when using lambda `fromImageAsset` As we are not allowed to specify `platform` flag for `DockerImageAsset`, users deploying cdk on x86_64 platform will not be able to bundle lambda.DockerImageFunction for the new arm64 architecture. Similarly, users deploying cdk on arm64 architecture like Mac M1 will not be able to bundle images for AWS Fargate, which is x86_64 only. # builder experience with aws-lambda For x86_64 users deploying Lambda functions with container runtime on Lambda Graviton2(arm64) from local container image assets with multi-architecture docker base images. Specify the platform to ensure the image would be built for ARM64 architecture. ``` new DockerImageFunction(stack, 'Lambda', { code: DockerImageCode.fromImageAsset(path.join(__dirname, 'docker-arm64-handler')), architecture: Architecture.ARM_64, }); ``` Fixes: #12472, #20907 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Based on [this](aws#16770) PR Add the missing part to add platform support when using lambda `fromImageAsset` As we are not allowed to specify `platform` flag for `DockerImageAsset`, users deploying cdk on x86_64 platform will not be able to bundle lambda.DockerImageFunction for the new arm64 architecture. Similarly, users deploying cdk on arm64 architecture like Mac M1 will not be able to bundle images for AWS Fargate, which is x86_64 only. # builder experience with aws-lambda For x86_64 users deploying Lambda functions with container runtime on Lambda Graviton2(arm64) from local container image assets with multi-architecture docker base images. Specify the platform to ensure the image would be built for ARM64 architecture. ``` new DockerImageFunction(stack, 'Lambda', { code: DockerImageCode.fromImageAsset(path.join(__dirname, 'docker-arm64-handler')), architecture: Architecture.ARM_64, }); ``` Fixes: aws#12472, aws#20907 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Use Case
To be able to build images for
amd64
architecture (e.g. AWS Fargate) on a system that is using other architecture likearm64
(e.g. Apple M1).Proposed Solution
Replace
docker build
withdocker buildx build
.https://docs.docker.com/buildx/working-with-buildx/#build-multi-platform-images
With
buildx
you can build cross-platform images by declaring--platform
argument. e.g.docker buildx build --platform linux/amd64 someimage:sometag .
executed on system Apple M1 results in an image which works system withamd64
architecture.buildx
allows you also to build image for multiple platforms at once. e.g.--platform linux/amd64,linux/arm64
Other
Currently image
.fromAsset
results in an image that works only on the same architecture where it was built. In that sense, this could be considered also a bug – the image built doesn't work on the target system (Fargate).This is a 🚀 Feature Request
The text was updated successfully, but these errors were encountered: