From a6ea16b7da3f747fc31b86edde25a0013376c6de Mon Sep 17 00:00:00 2001 From: Georg Ofenbeck Date: Tue, 7 May 2024 09:42:16 +0200 Subject: [PATCH] Add multi platform support to contrib.docker through docker buildx (#3143) A minor change to the contrib.docker plugin (and its docs). Allows to build for other architectures - a use case that becomes more and more useful with ARM architectures becoming more relevant. Relevant docs: [docker buildx (Buildkit)](https://docs.docker.com/reference/cli/docker/buildx/build/#platform) Pull request: https://github.com/com-lihaoyi/mill/pull/3143 --------- Co-authored-by: Georg Ofenbeck - taaofge1 --- contrib/docker/readme.adoc | 4 +++ .../mill/contrib/docker/DockerModule.scala | 31 ++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/contrib/docker/readme.adoc b/contrib/docker/readme.adoc index b12f8d5327e..6dd9dbe9de7 100644 --- a/contrib/docker/readme.adoc +++ b/contrib/docker/readme.adoc @@ -64,7 +64,11 @@ object docker extends DockerConfig { def user = "new-user" // Optionally override the docker executable to use something else def executable = "podman" + // If the executable is docker (which is also the default), you can optionally also pass a platform parameter + // docker buildx is then used to build multi-platform images + def platform = "linux/arm64" } ---- + Run mill in interactive mode to see the docker client output, like `mill -i foo.docker.build`. diff --git a/contrib/docker/src/mill/contrib/docker/DockerModule.scala b/contrib/docker/src/mill/contrib/docker/DockerModule.scala index 57c1308ad32..90e0c0943f7 100644 --- a/contrib/docker/src/mill/contrib/docker/DockerModule.scala +++ b/contrib/docker/src/mill/contrib/docker/DockerModule.scala @@ -84,6 +84,15 @@ trait DockerModule { outer: JavaModule => */ def user: T[String] = "" + /** + * Optional platform parameter, if set uses buildkit to build for specified platform. + * + * See also the Docker docs on + * [[https://docs.docker.com/reference/cli/docker/buildx/build/#platform]] + * for more information. + */ + def platform: T[String] = "" + /** * The name of the executable to use, the default is "docker". */ @@ -155,10 +164,24 @@ trait DockerModule { outer: JavaModule => val (pull, _) = pullAndHash() val pullLatestBase = IterableShellable(if (pull) Some("--pull") else None) - val result = os - .proc(executable(), "build", tagArgs, pullLatestBase, dest) - .call(stdout = os.Inherit, stderr = os.Inherit) - + val result = if (platform().isEmpty || executable() != "docker") { + if (platform().nonEmpty) + log.info("Platform parameter is ignored when using non-docker executable") + os.proc(executable(), "build", tagArgs, pullLatestBase, dest) + .call(stdout = os.Inherit, stderr = os.Inherit) + } else { + os.proc( + executable(), + "buildx", + "build", + tagArgs, + pullLatestBase, + "--platform", + platform(), + dest + ) + .call(stdout = os.Inherit, stderr = os.Inherit) + } log.info(s"Docker build completed ${if (result.exitCode == 0) "successfully" else "unsuccessfully"} with ${result.exitCode}") tags()