Browse code

Use buildx as Makefile builder

Since the dockerfile now requires buildkit, let's just use buildx can
bootstrap itself into even an old version of Docker which does not
support buildkit.

This also decouples the Dockerfile/build from the version of Docker
which is installed.

One major downside:

If buildx needs to setup a container driver (ie, docker does not support
buildkit), the `make shell` target (and others which call
`DOCKER_RUN_DOCKER`) must export the image from buildkit and into
docker. This added an extra 70s to a full build for me (agan only for targets
which call `DOCKER_RUN_DOCKER`) and 40s on a rebuild (with no changes).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2019/06/08 02:10:31
Showing 3 changed files
1 1
deleted file mode 100644
... ...
@@ -1,278 +0,0 @@
1
-# syntax=docker.io/docker/dockerfile:experimental@sha256:9022e911101f01b2854c7a4b2c77f524b998891941da55208e71c0335e6e82c3
2
-
3
-ARG CROSS="false"
4
-
5
-FROM golang:1.12.5 AS base
6
-# allow replacing httpredir or deb mirror
7
-ARG APT_MIRROR=deb.debian.org
8
-RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
9
-
10
-FROM base AS criu
11
-# Install CRIU for checkpoint/restore support
12
-ENV CRIU_VERSION 3.11
13
-# Install dependency packages specific to criu
14
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
15
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
16
-		apt-get update && apt-get install -y \
17
-			libnet-dev \
18
-			libprotobuf-c0-dev \
19
-			libprotobuf-dev \
20
-			libnl-3-dev \
21
-			libcap-dev \
22
-			protobuf-compiler \
23
-			protobuf-c-compiler \
24
-			python-protobuf \
25
-			&& mkdir -p /usr/src/criu \
26
-			&& curl -sSL https://github.com/checkpoint-restore/criu/archive/v${CRIU_VERSION}.tar.gz | tar -C /usr/src/criu/ -xz --strip-components=1 \
27
-			&& cd /usr/src/criu \
28
-			&& make \
29
-			&& make PREFIX=/build/ install-criu
30
-
31
-FROM base AS registry
32
-ENV REGISTRY_COMMIT 47a064d4195a9b56133891bbb13620c3ac83a827
33
-RUN set -x \
34
-	&& export GOPATH="$(mktemp -d)" \
35
-	&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
36
-	&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
37
-	&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
38
-		go build -buildmode=pie -o /build/registry-v2 github.com/docker/distribution/cmd/registry \
39
-	&& rm -rf "$GOPATH"
40
-
41
-
42
-
43
-FROM base AS docker-py
44
-# Get the "docker-py" source so we can run their integration tests
45
-ENV DOCKER_PY_COMMIT ac922192959870774ad8428344d9faa0555f7ba6
46
-RUN git clone https://github.com/docker/docker-py.git /build \
47
-	&& cd /build \
48
-	&& git checkout -q $DOCKER_PY_COMMIT
49
-
50
-
51
-
52
-FROM base AS swagger
53
-# Install go-swagger for validating swagger.yaml
54
-ENV GO_SWAGGER_COMMIT c28258affb0b6251755d92489ef685af8d4ff3eb
55
-RUN --mount=type=cache,id=gocache,target=/root/.cache/go-build set -x \
56
-	&& export GOPATH="$(mktemp -d)" \
57
-	&& git clone https://github.com/go-swagger/go-swagger.git "$GOPATH/src/github.com/go-swagger/go-swagger" \
58
-	&& (cd "$GOPATH/src/github.com/go-swagger/go-swagger" && git checkout -q "$GO_SWAGGER_COMMIT") \
59
-	&& go build -o /build/swagger github.com/go-swagger/go-swagger/cmd/swagger \
60
-	&& rm -rf "$GOPATH"
61
-
62
-
63
-FROM base AS frozen-images
64
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
65
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
66
-		apt-get update && apt-get install -y jq ca-certificates --no-install-recommends
67
-# Get useful and necessary Hub images so we can "docker load" locally instead of pulling
68
-COPY contrib/download-frozen-image-v2.sh /
69
-RUN /download-frozen-image-v2.sh /build \
70
-	buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
71
-	busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
72
-	busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \
73
-	debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
74
-	hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
75
-# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
76
-
77
-FROM base AS cross-false
78
-
79
-FROM base AS cross-true
80
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
81
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
82
-		dpkg --add-architecture armhf \
83
-		&& dpkg --add-architecture arm64 \
84
-		&& dpkg --add-architecture armel
85
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
86
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
87
-		if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
88
-		apt-get update \
89
-		&& apt-get install -y --no-install-recommends \
90
-			crossbuild-essential-armhf \
91
-			crossbuild-essential-arm64 \
92
-			crossbuild-essential-armel; \
93
-		fi
94
-
95
-FROM cross-${CROSS} as dev-base
96
-
97
-FROM dev-base AS runtime-dev-cross-false
98
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
99
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
100
-		apt-get update && apt-get install -y \
101
-			libapparmor-dev \
102
-			libseccomp-dev
103
-
104
-FROM cross-true AS runtime-dev-cross-true
105
-# These crossbuild packages rely on gcc-<arch>, but this doesn't want to install
106
-# on non-amd64 systems.
107
-# Additionally, the crossbuild-amd64 is currently only on debian:buster, so
108
-# other architectures cannnot crossbuild amd64.
109
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
110
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
111
-		if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
112
-			apt-get update \
113
-			&& apt-get install -y \
114
-				libseccomp-dev:armhf \
115
-				libseccomp-dev:arm64 \
116
-				libseccomp-dev:armel \
117
-				libapparmor-dev:armhf \
118
-				libapparmor-dev:arm64 \
119
-				libapparmor-dev:armel \
120
-				# install this arches seccomp here due to compat issues with the v0 builder
121
-				# This is as opposed to inheriting from runtime-dev-cross-false
122
-				libapparmor-dev \
123
-				libseccomp-dev; \
124
-		fi
125
-
126
-FROM runtime-dev-cross-${CROSS} AS runtime-dev
127
-
128
-FROM base AS tomlv
129
-ENV INSTALL_BINARY_NAME=tomlv
130
-COPY hack/dockerfile/install/install.sh ./install.sh
131
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
132
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
133
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
134
-
135
-FROM base AS vndr
136
-ENV INSTALL_BINARY_NAME=vndr
137
-COPY hack/dockerfile/install/install.sh ./install.sh
138
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
139
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
140
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
141
-
142
-FROM dev-base AS containerd
143
-RUN apt-get update && apt-get install -y btrfs-tools
144
-ENV INSTALL_BINARY_NAME=containerd
145
-COPY hack/dockerfile/install/install.sh ./install.sh
146
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
147
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
148
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
149
-
150
-FROM dev-base AS proxy
151
-ENV INSTALL_BINARY_NAME=proxy
152
-COPY hack/dockerfile/install/install.sh ./install.sh
153
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
154
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
155
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
156
-
157
-FROM base AS gometalinter
158
-ENV INSTALL_BINARY_NAME=gometalinter
159
-COPY hack/dockerfile/install/install.sh ./install.sh
160
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
161
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
162
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
163
-
164
-FROM dev-base AS dockercli
165
-ENV INSTALL_BINARY_NAME=dockercli
166
-COPY hack/dockerfile/install/install.sh ./install.sh
167
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
168
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
169
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
170
-
171
-FROM runtime-dev AS runc
172
-ENV INSTALL_BINARY_NAME=runc
173
-COPY hack/dockerfile/install/install.sh ./install.sh
174
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
175
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
176
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
177
-
178
-FROM dev-base AS tini
179
-RUN apt-get update && apt-get install -y cmake vim-common
180
-COPY hack/dockerfile/install/install.sh ./install.sh
181
-ENV INSTALL_BINARY_NAME=tini
182
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
183
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
184
-	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
185
-
186
-FROM dev-base AS rootlesskit
187
-ENV INSTALL_BINARY_NAME=rootlesskit
188
-COPY hack/dockerfile/install/install.sh ./install.sh
189
-COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
190
-RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
191
-	PREFIX=/build/ ./install.sh $INSTALL_BINARY_NAME
192
-COPY ./contrib/dockerd-rootless.sh /build
193
-
194
-# TODO: Some of this is only really needed for testing, it would be nice to split this up
195
-FROM runtime-dev AS dev
196
-RUN groupadd -r docker
197
-RUN useradd --create-home --gid docker unprivilegeduser
198
-# Let us use a .bashrc file
199
-RUN ln -sfv /go/src/github.com/docker/docker/.bashrc ~/.bashrc
200
-# Activate bash completion and include Docker's completion if mounted with DOCKER_BASH_COMPLETION_PATH
201
-RUN echo "source /usr/share/bash-completion/bash_completion" >> /etc/bash.bashrc
202
-RUN ln -s /usr/local/completion/bash/docker /etc/bash_completion.d/docker
203
-RUN ldconfig
204
-# This should only install packages that are specifically needed for the dev environment and nothing else
205
-# Do you really need to add another package here? Can it be done in a different build stage?
206
-RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
207
-	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
208
-apt-get update && apt-get install -y \
209
-	apparmor \
210
-	aufs-tools \
211
-	bash-completion \
212
-	btrfs-tools \
213
-	iptables \
214
-	jq \
215
-	libcap2-bin \
216
-	libdevmapper-dev \
217
-# libffi-dev and libssl-dev appear to be required for compiling paramiko on s390x/ppc64le
218
-	libffi-dev \
219
-	libssl-dev \
220
-	libudev-dev \
221
-	libsystemd-dev \
222
-	binutils-mingw-w64 \
223
-	g++-mingw-w64-x86-64 \
224
-	net-tools \
225
-	pigz \
226
-	python-backports.ssl-match-hostname \
227
-	python-dev \
228
-# python-cffi appears to be required for compiling paramiko on s390x/ppc64le
229
-	python-cffi \
230
-	python-mock \
231
-	python-pip \
232
-	python-requests \
233
-	python-setuptools \
234
-	python-websocket \
235
-	python-wheel \
236
-	thin-provisioning-tools \
237
-	vim \
238
-	vim-common \
239
-	xfsprogs \
240
-	zip \
241
-	bzip2 \
242
-	xz-utils \
243
-	libprotobuf-c1 \
244
-	libnet1 \
245
-	libnl-3-200 \
246
-	--no-install-recommends
247
-COPY --from=swagger /build/swagger* /usr/local/bin/
248
-COPY --from=frozen-images /build/ /docker-frozen-images
249
-COPY --from=gometalinter /build/ /usr/local/bin/
250
-COPY --from=tomlv /build/ /usr/local/bin/
251
-COPY --from=vndr /build/ /usr/local/bin/
252
-COPY --from=tini /build/ /usr/local/bin/
253
-COPY --from=runc /build/ /usr/local/bin/
254
-COPY --from=containerd /build/ /usr/local/bin/
255
-COPY --from=proxy /build/ /usr/local/bin/
256
-COPY --from=dockercli /build/ /usr/local/cli
257
-COPY --from=registry /build/registry* /usr/local/bin/
258
-COPY --from=criu /build/ /usr/local/
259
-COPY --from=docker-py /build/ /docker-py
260
-COPY --from=rootlesskit /build/ /usr/local/bin/
261
-COPY --from=djs55/vpnkit@sha256:e508a17cfacc8fd39261d5b4e397df2b953690da577e2c987a47630cd0c42f8e /vpnkit /usr/local/bin/vpnkit.x86_64
262
-
263
-ENV PATH=/usr/local/cli:$PATH
264
-ENV DOCKER_BUILDTAGS apparmor seccomp selinux
265
-# Options for hack/validate/gometalinter
266
-ENV GOMETALINTER_OPTS="--deadline=2m"
267
-WORKDIR /go/src/github.com/docker/docker
268
-VOLUME /var/lib/docker
269
-# Wrap all commands in the "docker-in-docker" script to allow nested containers
270
-ENTRYPOINT ["hack/dind"]
271
-
272
-FROM dev AS final
273
-# Upload docker source
274
-COPY . /go/src/github.com/docker/docker
275
-ARG DOCKER_GITCOMMIT=HEAD
276
-RUN --mount=type=cache,id=gocache,target=/root/.cache/go-build \
277
-	hack/make.sh binary
278
-RUN hack/make.sh install-binary
279 1
new file mode 100644
... ...
@@ -0,0 +1,14 @@
0
+ARG GO_VERSION=1.12.10
1
+FROM golang:${GO_VERSION}-stretch
2
+ARG BUILDX_REPO=https://github.com/docker/buildx.git
3
+RUN git clone "${BUILDX_REPO}" /buildx
4
+WORKDIR /buildx
5
+ARG BUILDX_COMMIT=master
6
+RUN git fetch origin "${BUILDX_COMMIT}":build && git checkout build
7
+RUN go mod download
8
+ARG GOOS
9
+ARG GOARCH
10
+# Keep these essentially no-op var settings for debug purposes.
11
+# It allows us to see what the GOOS/GOARCH that's being built for is.
12
+RUN GOOS=${GOOS} GOARCH=${GOARCH} go build -ldflags '-X github.com/docker/buildx/version.Version=${BUILDX_COMMIT} -X github.com/docker/buildx/version.Revision=${BUILDX_COMMIT} -X github.com/docker/buildx/version.Package=github.com/docker/buildx' -o /usr/bin/buildx ./cmd/buildx
13
+ENTRYPOINT ["/usr/bin/buildx"]
0 14
\ No newline at end of file
... ...
@@ -1,5 +1,15 @@
1 1
 .PHONY: all binary dynbinary build cross help install manpages run shell test test-docker-py test-integration test-unit validate win
2 2
 
3
+ifdef USE_BUILDX
4
+BUILDX ?= $(shell command -v buildx)
5
+BUILDX ?= $(shell command -v docker-buildx)
6
+DOCKER_BUILDX_CLI_PLUGIN_PATH ?= ~/.docker/cli-plugins/docker-buildx
7
+BUILDX ?= $(shell if [ -x "$(DOCKER_BUILDX_CLI_PLUGIN_PATH)" ]; then echo $(DOCKER_BUILDX_CLI_PLUGIN_PATH); fi)
8
+endif
9
+
10
+BUILDX ?= bundles/buildx
11
+DOCKER ?= docker
12
+
3 13
 # set the graph driver as the current graphdriver if not set
4 14
 DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
5 15
 export DOCKER_GRAPHDRIVER
... ...
@@ -107,7 +117,7 @@ GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
107 107
 DOCKER_IMAGE := docker-dev$(if $(GIT_BRANCH_CLEAN),:$(GIT_BRANCH_CLEAN))
108 108
 DOCKER_PORT_FORWARD := $(if $(DOCKER_PORT),-p "$(DOCKER_PORT)",)
109 109
 
110
-DOCKER_FLAGS := docker run --rm -i --privileged $(DOCKER_CONTAINER_NAME) $(DOCKER_ENVS) $(DOCKER_MOUNT) $(DOCKER_PORT_FORWARD)
110
+DOCKER_FLAGS := $(DOCKER) run --rm -i --privileged $(DOCKER_CONTAINER_NAME) $(DOCKER_ENVS) $(DOCKER_MOUNT) $(DOCKER_PORT_FORWARD)
111 111
 BUILD_APT_MIRROR := $(if $(DOCKER_BUILD_APT_MIRROR),--build-arg APT_MIRROR=$(DOCKER_BUILD_APT_MIRROR))
112 112
 export BUILD_APT_MIRROR
113 113
 
... ...
@@ -133,29 +143,30 @@ default: binary
133 133
 all: build ## validate all checks, build linux binaries, run all tests\ncross build non-linux binaries and generate archives
134 134
 	$(DOCKER_RUN_DOCKER) bash -c 'hack/validate/default && hack/make.sh'
135 135
 
136
+binary: DOCKER_BUILD_ARGS += --output=bundles/ --target=binary
136 137
 binary: build ## build the linux binaries
137
-	$(DOCKER_RUN_DOCKER) hack/make.sh binary
138 138
 
139
+dynbinary: DOCKER_BUILD_ARGS += --output=bundles/ --target=dynbinary
139 140
 dynbinary: build ## build the linux dynbinaries
140
-	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary
141
-
142
-
143 141
 
142
+cross: DOCKER_BUILD_ARGS += --output=bundles/ --target=cross --build-arg DOCKER_CROSSPLATFORMS=$(DOCKER_CROSSPLATFORMS)
144 143
 cross: DOCKER_CROSS := true
145 144
 cross: build ## cross build the binaries for darwin, freebsd and\nwindows
146
-	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary binary cross
147 145
 
148 146
 ifdef DOCKER_CROSSPLATFORMS
149 147
 build: DOCKER_CROSS := true
150 148
 endif
151
-ifeq ($(BIND_DIR), .)
152
-build: DOCKER_BUILD_OPTS += --target=dev
153
-endif
154 149
 build: DOCKER_BUILD_ARGS += --build-arg=CROSS=$(DOCKER_CROSS)
155
-build: DOCKER_BUILDKIT ?= 1
150
+ifdef GO_VERSION
151
+build: DOCKER_BUILD_ARGS += --build-arg=GO_VERSION=$(GO_VERSION)
152
+endif
153
+ifdef USE_BUILDX
154
+build: bundles buildx 
155
+	$(BUILDX) build ${BUILD_APT_MIRROR} ${DOCKER_BUILD_ARGS} ${DOCKER_BUILD_OPTS} -t "$(DOCKER_IMAGE)" -f "$(DOCKERFILE)" $(BUILDX_BUILD_EXTRA_OPTS) .
156
+else
156 157
 build: bundles
157
-	$(warning The docker client CLI has moved to github.com/docker/cli. For a dev-test cycle involving the CLI, run:${\n} DOCKER_CLI_PATH=/host/path/to/cli/binary make shell ${\n} then change the cli and compile into a binary at the same location.${\n})
158
-	DOCKER_BUILDKIT="${DOCKER_BUILDKIT}" docker build --build-arg=GO_VERSION ${BUILD_APT_MIRROR} ${DOCKER_BUILD_ARGS} ${DOCKER_BUILD_OPTS} -t "$(DOCKER_IMAGE)" -f "$(DOCKERFILE)" .
158
+	$(DOCKER) build ${BUILD_APT_MIRROR} ${DOCKER_BUILD_ARGS} ${DOCKER_BUILD_OPTS} -t "$(DOCKER_IMAGE)" -f "$(DOCKERFILE)" .
159
+endif
159 160
 
160 161
 bundles:
161 162
 	mkdir bundles
... ...
@@ -176,7 +187,9 @@ install: ## install the linux binaries
176 176
 run: build ## run the docker daemon in a container
177 177
 	$(DOCKER_RUN_DOCKER) sh -c "KEEPBUNDLE=1 hack/make.sh install-binary run"
178 178
 
179
-shell: build ## start a shell inside the build env
179
+shell: DOCKER_BUILD_ARGS += --target=dev
180
+shell: BUILDX_BUILD_EXTRA_OPTS += --load
181
+shell: build  ## start a shell inside the build env
180 182
 	$(DOCKER_RUN_DOCKER) bash
181 183
 
182 184
 test: build test-unit ## run the unit, integration and docker-py tests
... ...
@@ -222,3 +235,24 @@ swagger-docs: ## preview the API documentation
222 222
 		-e 'REDOC_OPTIONS=hide-hostname="true" lazy-rendering' \
223 223
 		-p $(SWAGGER_DOCS_PORT):80 \
224 224
 		bfirsh/redoc:1.6.2
225
+
226
+.PHONY: buildx
227
+ifeq ($(BUILDX), bundles/buildx)
228
+buildx: bundles/buildx # build buildx cli tool
229
+else
230
+buildx:
231
+endif
232
+
233
+bundles/buildx: BUILDX_DOCKERFILE ?= Dockerfile.buildx
234
+bundles/buildx: BUILDX_COMMIT ?= v0.3.0
235
+bundles/buildx: bundles ## build buildx CLI tool
236
+	# This intetionally is not using the `--output` flag from the docker CLI which is a buildkit option
237
+	# The idea here being that if buildx is being used, it's because buildkit is not supported natively
238
+	docker build -f $(BUILDX_DOCKERFILE) -t "moby-buildx:$(BUILDX_COMMIT)" \
239
+		--build-arg BUILDX_COMMIT \
240
+		--build-arg BUILDX_REPO \
241
+		--build-arg GOOS=$$(if [ -n "$(GOOS)" ]; then echo $(GOOS); else go env GOHOSTOS || uname | awk '{print tolower($$0)}' || true; fi) \
242
+		--build-arg GOARCH=$$(if [ -n "$(GOARCH)" ]; then echo $(GOARCH); else go env GOHOSTARCH || true; fi) \
243
+		. && \
244
+		id=$$(docker create moby-buildx:$(BUILDX_COMMIT)); \
245
+		if [ -n "$${id}" ]; then docker cp $${id}:/usr/bin/buildx $@ && touch $@; docker rm -f $${id}; fi