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
docker backend support buildx cross platform builds without containerd-snapshotter #20728
base: main
Are you sure you want to change the base?
Conversation
…ds without containerd-snapshotter package docker buildx build --output=type=docker --pull=False --tag <snip> --file src/Dockerfile . publish docker buildx build --platform=linux/amd64,linux/arm64 --pull=False --push --tag <snip> --file src/Dockerfile .
build_setup = await Get( | ||
DockerBuildSetup, | ||
DockerBuildSetupRequest( | ||
field_set=DockerPackageFieldSet.create(target), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The publish goal is awkward for these targets because while they have a package already, its not usable. We need to re-invoke docker buildx build
with the --push
flag and --platform
return PublishProcesses( | ||
[ | ||
PublishPackages( | ||
# TODO deal with tags that are intended to be skipped |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll need to move all tag/registry logic into the DockerBuildSetup rule also
|
||
@rule | ||
async def build_docker_image( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
build_docker_image
was split up so I can re-use the majority of it from publish
@@ -343,6 +347,16 @@ def get_build_options( | |||
DockerBuildOptionFlagFieldMixin, | |||
), | |||
): | |||
if ignore_platforms and field_type == DockerImageBuildPlatformOptionField: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to apply slightly different options to package
and publish
. Theres probably a nicer way I could clean this up
f"The `--push` flag was set on the command line, but buildx is not enabled. " | ||
f"Buildx must be enabled via the Docker subsystem options in order to use this flag." | ||
) | ||
yield "--push" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--push
is a "shortcut" flag, we can accomplish the same thing if we set --output=type=image,push=true
I like the general direction here. We likely want this to be optional at every step--possibly with some detection logic to do the sensible thing by default. (like using the Also, in case publish does a build+push combo, avoid requesting the normal I'm about to head off on easter vacation, so will be more or less offline until April 8. |
This does happen right now, how can I accomplish this?
Enjoy your vacation! |
Fixes #19994
Currently the docker cross-platform build support relies on using
containerd-snapshotter
https://www.pantsbuild.org/2.19/docs/docker#buildx-support which may not be desirable. The feature itself is still experimental and testing within our org encountered both performance problems and bugs that prevent adoption.We're currently building/publishing cross-platform images using buildx and the docker-container driver
This is a very rough draft to allow the docker backend to support buildx cross platform builds without containerd-snapshotter.
I outlined the challenges in slack but I'll repeat them here for posterity.
--platform
flag or not specifypackage
andpublish
need to behave differently when using buildx cross platform without containerd-snapshotterExample commands that this would invoke
package
docker buildx build --output=type=docker --pull=False --tag --file src/Dockerfile .
publish
docker buildx build --platform=linux/amd64,linux/arm64 --pull=False --push --tag --file src/Dockerfile .
Misc Discussion Points
Should the
package
goal should prefer to build all platforms or to export the image to the docker driver? Should be configurable? It is somewhat awkward to havepackage
not actually build all the artifacts, but at least for our use case, we prefer to build and test the image in the CI pipeline, which necessitates outputting to docker driver.Should pants detect if
containerd-snapshotter
is being used?docker info -f '{{ .DriverStatus }}'
can be used for this If not, should there be a setting on the subsystem?Testing locally
If you want to test locally, first you must create the buildx builder like
Right now I'm forcing the use of a particular buildx builder via env var on the subsystem, but I don't love this as it applies to all targets. I think adding a field for this on docker_image would make sense (
--builder
cli flag)