Skip to content

builder: Proposal: Add TARGETPLATFORM/BUILDPLATFORM default ARG to Dockerfile #32487

Closed
@tonistiigi

Description

I've updated this proposal to match the implementation in moby/buildkit#499 . If you want to see the old proposal with different ARG names it is in https://gist.github.com/tonistiigi/79800156a5300336c24000cd78440a15

To enable configuring Dockerfile behavior based on the target platform or the platform of the node doing the build values of some predefined build args would be filled automatically.

These ars are:

TARGETPLATFORM
TARGETOS
TARGETARCH
TARGETVARIANT

BUILDPLATFORM
BUILDOS
BUILDARCH
BUILDVARIANT

TARGETPLATFORM/BUILDPLATFORM contain the normalized platform string value defined in https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17 . This is the same format accepted by docker build --platform or FROM --platform=.

TARGET* args are automatically filled with the value specified in docker build --platform. If no flag is specified this defaults to current platform. FROM command without --platform flag is equal to FROM --platform=$TARGETPLATFORM (this is the current behavior).

The *OS/*ARCH/*VARIANT vars are just different components of the main *PLATFORM value.

BUILD* args are automatically filled with the platform detected from current system. If system supports multiple platforms this is the default one.

The main use case for these variables would be to use them in multi-stage builds in combination with #31352. For example:

FROM alpine AS build-env-linux
...
FROM microsoft/nanoserver AS build-env-windows
...
FROM build-env-${TARGETOS}

Building this with docker build -t myimage . would now work both in linux and windows. Note that you would also need to use BuildKit for this to be efficient and skip unused commands.

They can also be used for cross compilation. In this example build stage is fixed to worker architecture but for the exported stage, alpine for target architecture is used.

FROM --from=$BUILDPLATFORM golang:alpine as build
ARG TARGETOS
ARG TARGETARCH
ENV GOOS=$TARGETOS GOARCH=$TARGETARCH
RUN go build ...

FROM alpine
COPY --from=build binary /bin

The build arguments are defined in global scope, meaning they can be used for argument substitution in FROM commands but do not automatically leak to your processes. To make them available inside the stage they need to be exposed with ARG like regular global scope arguments.

For more compatibility with older builders these args can be overriden by the user with --build-arg so if more control is needed or a new Dockerfile is build on old system it can still be used.

@dnephin @tiborvass

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions