Forráskód Böngészése

Buildkit-optimized dockerfile

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff 6 éve
szülő
commit
82c56755ea
2 módosított fájl, 448 hozzáadás és 133 törlés
  1. 170 133
      Dockerfile
  2. 278 0
      Dockerfile.buildkit

+ 170 - 133
Dockerfile

@@ -1,34 +1,11 @@
-# This file describes the standard way to build Docker, using docker
-#
-# Usage:
-#
-# # Use make to build a development environment image and run it in a container.
-# # This is slow the first time.
-# make BIND_DIR=. shell
-#
-# The following commands are executed inside the running container.
-
-# # Make a dockerd binary.
-# # hack/make.sh binary
-#
-# # Install dockerd to /usr/local/bin
-# # make install
-#
-# # Run unit tests
-# # hack/test/unit
-#
-# # Run tests e.g. integration, py
-# # hack/make.sh binary test-integration test-docker-py
-#
-# Note: AppArmor used to mess with privileged mode, but this is no longer
-# the case. Therefore, you don't have to disable it anymore.
-#
+# syntax=docker/dockerfile:1.1.3-experimental
 
 ARG CROSS="false"
 ARG GO_VERSION=1.13.1
 ARG DEBIAN_FRONTEND=noninteractive
 
 FROM golang:${GO_VERSION}-stretch AS base
+RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
 ARG APT_MIRROR
 RUN sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/apt/sources.list \
  && sed -ri "s/(security).debian.org/${APT_MIRROR:-security.debian.org}/g" /etc/apt/sources.list
@@ -36,19 +13,21 @@ ENV GO111MODULE=off
 
 FROM base AS criu
 ARG DEBIAN_FRONTEND
+# Install dependency packages specific to criu
+RUN --mount=type=cache,sharing=locked,id=moby-criu-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-criu-aptcache,target=/var/cache/apt \
+		apt-get update && apt-get install -y --no-install-recommends \
+			libnet-dev \
+			libprotobuf-c-dev \
+			libprotobuf-dev \
+			libnl-3-dev \
+			libcap-dev \
+			protobuf-compiler \
+			protobuf-c-compiler \
+			python-protobuf
+
 # Install CRIU for checkpoint/restore support
 ENV CRIU_VERSION 3.12
-# Install dependency packages specific to criu
-RUN apt-get update && apt-get install -y --no-install-recommends \
-	libnet-dev \
-	libprotobuf-c-dev \
-	libprotobuf-dev \
-	libnl-3-dev \
-	libcap-dev \
-	protobuf-compiler \
-	protobuf-c-compiler \
-	python-protobuf \
-	&& rm -rf /var/lib/apt/lists/*
 RUN mkdir -p /usr/src/criu \
 	&& curl -sSL https://github.com/checkpoint-restore/criu/archive/v${CRIU_VERSION}.tar.gz | tar -C /usr/src/criu/ -xz --strip-components=1 \
 	&& cd /usr/src/criu \
@@ -62,37 +41,42 @@ FROM base AS registry
 # and schema2 manifests.
 ENV REGISTRY_COMMIT_SCHEMA1 ec87e9b6971d831f0eff752ddb54fb64693e51cd
 ENV REGISTRY_COMMIT 47a064d4195a9b56133891bbb13620c3ac83a827
-RUN set -x \
-	&& export GOPATH="$(mktemp -d)" \
-	&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
-	&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
-	&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
-		go build -buildmode=pie -o /build/registry-v2 github.com/docker/distribution/cmd/registry \
-	&& case $(dpkg --print-architecture) in \
-		amd64|ppc64*|s390x) \
-		(cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT_SCHEMA1"); \
-		GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH"; \
-			go build -buildmode=pie -o /build/registry-v2-schema1 github.com/docker/distribution/cmd/registry; \
-		;; \
-	   esac \
-	&& rm -rf "$GOPATH"
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		set -x \
+		&& export GOPATH="$(mktemp -d)" \
+		&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
+		&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
+		&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
+			go build -buildmode=pie -o /build/registry-v2 github.com/docker/distribution/cmd/registry \
+		&& case $(dpkg --print-architecture) in \
+			amd64|ppc64*|s390x) \
+			(cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT_SCHEMA1"); \
+			GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH"; \
+				go build -buildmode=pie -o /build/registry-v2-schema1 github.com/docker/distribution/cmd/registry; \
+			;; \
+			 esac \
+		&& rm -rf "$GOPATH"
 
 FROM base AS swagger
 # Install go-swagger for validating swagger.yaml
 ENV GO_SWAGGER_COMMIT c28258affb0b6251755d92489ef685af8d4ff3eb
-RUN set -x \
-	&& export GOPATH="$(mktemp -d)" \
-	&& git clone https://github.com/go-swagger/go-swagger.git "$GOPATH/src/github.com/go-swagger/go-swagger" \
-	&& (cd "$GOPATH/src/github.com/go-swagger/go-swagger" && git checkout -q "$GO_SWAGGER_COMMIT") \
-	&& go build -o /build/swagger github.com/go-swagger/go-swagger/cmd/swagger \
-	&& rm -rf "$GOPATH"
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		set -x \
+		&& export GOPATH="$(mktemp -d)" \
+		&& git clone https://github.com/go-swagger/go-swagger.git "$GOPATH/src/github.com/go-swagger/go-swagger" \
+		&& (cd "$GOPATH/src/github.com/go-swagger/go-swagger" && git checkout -q "$GO_SWAGGER_COMMIT") \
+		&& go build -o /build/swagger github.com/go-swagger/go-swagger/cmd/swagger \
+		&& rm -rf "$GOPATH"
 
 FROM base AS frozen-images
 ARG DEBIAN_FRONTEND
-RUN apt-get update && apt-get install -y --no-install-recommends \
-	ca-certificates \
-	jq \
-	&& rm -rf /var/lib/apt/lists/*
+RUN --mount=type=cache,sharing=locked,id=moby-frozen-images-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-frozen-images-aptcache,target=/var/cache/apt \
+		apt-get update && apt-get install -y --no-install-recommends \
+		ca-certificates \
+		jq
 # Get useful and necessary Hub images so we can "docker load" locally instead of pulling
 COPY contrib/download-frozen-image-v2.sh /
 RUN /download-frozen-image-v2.sh /build \
@@ -110,42 +94,47 @@ ARG DEBIAN_FRONTEND
 RUN dpkg --add-architecture armhf
 RUN dpkg --add-architecture arm64
 RUN dpkg --add-architecture armel
-RUN if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
-	apt-get update && apt-get install -y --no-install-recommends \
-		crossbuild-essential-armhf \
-		crossbuild-essential-arm64 \
-		crossbuild-essential-armel \
-		&& rm -rf /var/lib/apt/lists/*; \
-	fi
+RUN --mount=type=cache,sharing=locked,id=moby-cross-true-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-cross-true-aptcache,target=/var/cache/apt \
+		if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
+			apt-get update && apt-get install -y --no-install-recommends \
+			crossbuild-essential-armhf \
+			crossbuild-essential-arm64 \
+			crossbuild-essential-armel \
+		fi
 
 FROM cross-${CROSS} as dev-base
 
 FROM dev-base AS runtime-dev-cross-false
 ARG DEBIAN_FRONTEND
-RUN apt-get update && apt-get install -y --no-install-recommends \
-	libapparmor-dev \
-	libseccomp-dev \
-	&& rm -rf /var/lib/apt/lists/*
+RUN --mount=type=cache,sharing=locked,id=moby-cross-false-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-cross-false-aptcache,target=/var/cache/apt \
+		apt-get update && apt-get install -y --no-install-recommends \
+		libapparmor-dev \
+		libseccomp-dev
+
 FROM cross-true AS runtime-dev-cross-true
 ARG DEBIAN_FRONTEND
 # These crossbuild packages rely on gcc-<arch>, but this doesn't want to install
 # on non-amd64 systems.
 # Additionally, the crossbuild-amd64 is currently only on debian:buster, so
 # other architectures cannnot crossbuild amd64.
-RUN if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
-	apt-get update && apt-get install -y --no-install-recommends \
-		libseccomp-dev:armhf \
-		libseccomp-dev:arm64 \
-		libseccomp-dev:armel \
-		libapparmor-dev:armhf \
-		libapparmor-dev:arm64 \
-		libapparmor-dev:armel \
-		# install this arches seccomp here due to compat issues with the v0 builder
-		# This is as opposed to inheriting from runtime-dev-cross-false
-		libapparmor-dev \
-		libseccomp-dev \
-		&& rm -rf /var/lib/apt/lists/*; \
-	fi
+RUN --mount=type=cache,sharing=locked,id=moby-cross-true-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-cross-true-aptcache,target=/var/cache/apt \
+		if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
+			apt-get update && apt-get install -y --no-install-recommends \
+				libseccomp-dev:armhf \
+				libseccomp-dev:arm64 \
+				libseccomp-dev:armel \
+				libapparmor-dev:armhf \
+				libapparmor-dev:arm64 \
+				libapparmor-dev:armel \
+				# install this arches seccomp here due to compat issues with the v0 builder
+				# This is as opposed to inheriting from runtime-dev-cross-false
+				libapparmor-dev \
+				libseccomp-dev \
+		fi
+
 
 FROM runtime-dev-cross-${CROSS} AS runtime-dev
 
@@ -153,70 +142,92 @@ FROM base AS tomlv
 ENV INSTALL_BINARY_NAME=tomlv
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM base AS vndr
 ENV INSTALL_BINARY_NAME=vndr
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM dev-base AS containerd
 ARG DEBIAN_FRONTEND
-RUN apt-get update && apt-get install -y --no-install-recommends \
-	btrfs-tools \
-	&& rm -rf /var/lib/apt/lists/*
+RUN --mount=type=cache,sharing=locked,id=moby-containerd-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-containerd-aptcache,target=/var/cache/apt \
+		apt-get update && apt-get install -y --no-install-recommends \
+			btrfs-tools
 ENV INSTALL_BINARY_NAME=containerd
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM dev-base AS proxy
 ENV INSTALL_BINARY_NAME=proxy
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM base AS golangci_lint
 ENV INSTALL_BINARY_NAME=golangci_lint
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM base AS gotestsum
 ENV INSTALL_BINARY_NAME=gotestsum
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM dev-base AS dockercli
 ENV INSTALL_BINARY_NAME=dockercli
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM runtime-dev AS runc
 ENV INSTALL_BINARY_NAME=runc
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM dev-base AS tini
 ARG DEBIAN_FRONTEND
-RUN apt-get update && apt-get install -y --no-install-recommends \
-	cmake \
-	vim-common \
-	&& rm -rf /var/lib/apt/lists/*
+RUN --mount=type=cache,sharing=locked,id=moby-tini-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-tini-aptcache,target=/var/cache/apt \
+		apt-get update && apt-get install -y --no-install-recommends \
+			cmake \
+			vim-common
 COPY hack/dockerfile/install/install.sh ./install.sh
 ENV INSTALL_BINARY_NAME=tini
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
 
 FROM dev-base AS rootlesskit
 ENV INSTALL_BINARY_NAME=rootlesskit
 COPY hack/dockerfile/install/install.sh ./install.sh
 COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
-RUN PREFIX=/build/ ./install.sh $INSTALL_BINARY_NAME
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	--mount=type=cache,target=/go/pkg/mod \
+		PREFIX=/build/ ./install.sh $INSTALL_BINARY_NAME
 COPY ./contrib/dockerd-rootless.sh /build
 
 # TODO: Some of this is only really needed for testing, it would be nice to split this up
@@ -232,35 +243,37 @@ RUN ln -s /usr/local/completion/bash/docker /etc/bash_completion.d/docker
 RUN ldconfig
 # This should only install packages that are specifically needed for the dev environment and nothing else
 # Do you really need to add another package here? Can it be done in a different build stage?
-RUN apt-get update && apt-get install -y --no-install-recommends \
-	apparmor \
-	aufs-tools \
-	bash-completion \
-	btrfs-tools \
-	iptables \
-	jq \
-	libcap2-bin \
-	libdevmapper-dev \
-	libudev-dev \
-	libsystemd-dev \
-	binutils-mingw-w64 \
-	g++-mingw-w64-x86-64 \
-	net-tools \
-	pigz \
-	python3-pip \
-	python3-setuptools \
-	python3-wheel \
-	thin-provisioning-tools \
-	vim \
-	vim-common \
-	xfsprogs \
-	zip \
-	bzip2 \
-	xz-utils \
-	libprotobuf-c1 \
-	libnet1 \
-	libnl-3-200 \
-	&& rm -rf /var/lib/apt/lists/*
+RUN --mount=type=cache,sharing=locked,id=moby-dev-aptlib,target=/var/lib/apt \
+	--mount=type=cache,sharing=locked,id=moby-dev-aptcache,target=/var/cache/apt \
+		apt-get update && apt-get install -y --no-install-recommends \
+		apparmor \
+		aufs-tools \
+		bash-completion \
+		btrfs-tools \
+		iptables \
+		jq \
+		libcap2-bin \
+		libdevmapper-dev \
+		libudev-dev \
+		libsystemd-dev \
+		binutils-mingw-w64 \
+		g++-mingw-w64-x86-64 \
+		net-tools \
+		pigz \
+		python3-pip \
+		python3-setuptools \
+		python3-wheel \
+		thin-provisioning-tools \
+		vim \
+		vim-common \
+		xfsprogs \
+		zip \
+		bzip2 \
+		xz-utils \
+		libprotobuf-c1 \
+		libnet1 \
+		libnl-3-200
+
 
 RUN pip3 install yamllint==1.16.0
 
@@ -286,7 +299,31 @@ WORKDIR /go/src/github.com/docker/docker
 VOLUME /var/lib/docker
 # Wrap all commands in the "docker-in-docker" script to allow nested containers
 ENTRYPOINT ["hack/dind"]
+COPY . /go/src/github.com/docker/docker
+
+FROM dev AS build-binary
+ARG DOCKER_GITCOMMIT=HEAD
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	hack/make.sh binary
+
+FROM dev AS build-dynbinary
+ARG DOCKER_GITCOMMIT=HEAD
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	hack/make.sh dynbinary
+
+FROM dev AS build-cross
+ARG DOCKER_GITCOMMIT=HEAD
+ARG DOCKER_CROSSPLATFORMS=""
+RUN --mount=type=cache,target=/root/.cache/go-build \
+	hack/make.sh cross
+
+FROM scratch AS binary
+COPY --from=build-binary /go/src/github.com/docker/docker/bundles/ /
+
+FROM scratch AS dynbinary
+COPY --from=build-dynbinary /go/src/github.com/docker/docker/bundles/ /
+
+FROM scratch AS cross
+COPY --from=build-cross /go/src/github.com/docker/docker/bundles/ /
 
 FROM dev AS final
-# Upload docker source
-COPY . /go/src/github.com/docker/docker

+ 278 - 0
Dockerfile.buildkit

@@ -0,0 +1,278 @@
+# syntax=docker.io/docker/dockerfile:experimental@sha256:9022e911101f01b2854c7a4b2c77f524b998891941da55208e71c0335e6e82c3
+
+ARG CROSS="false"
+
+FROM golang:1.12.5 AS base
+# allow replacing httpredir or deb mirror
+ARG APT_MIRROR=deb.debian.org
+RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
+
+FROM base AS criu
+# Install CRIU for checkpoint/restore support
+ENV CRIU_VERSION 3.11
+# Install dependency packages specific to criu
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+		apt-get update && apt-get install -y \
+			libnet-dev \
+			libprotobuf-c0-dev \
+			libprotobuf-dev \
+			libnl-3-dev \
+			libcap-dev \
+			protobuf-compiler \
+			protobuf-c-compiler \
+			python-protobuf \
+			&& mkdir -p /usr/src/criu \
+			&& curl -sSL https://github.com/checkpoint-restore/criu/archive/v${CRIU_VERSION}.tar.gz | tar -C /usr/src/criu/ -xz --strip-components=1 \
+			&& cd /usr/src/criu \
+			&& make \
+			&& make PREFIX=/build/ install-criu
+
+FROM base AS registry
+ENV REGISTRY_COMMIT 47a064d4195a9b56133891bbb13620c3ac83a827
+RUN set -x \
+	&& export GOPATH="$(mktemp -d)" \
+	&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
+	&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
+	&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
+		go build -buildmode=pie -o /build/registry-v2 github.com/docker/distribution/cmd/registry \
+	&& rm -rf "$GOPATH"
+
+
+
+FROM base AS docker-py
+# Get the "docker-py" source so we can run their integration tests
+ENV DOCKER_PY_COMMIT ac922192959870774ad8428344d9faa0555f7ba6
+RUN git clone https://github.com/docker/docker-py.git /build \
+	&& cd /build \
+	&& git checkout -q $DOCKER_PY_COMMIT
+
+
+
+FROM base AS swagger
+# Install go-swagger for validating swagger.yaml
+ENV GO_SWAGGER_COMMIT c28258affb0b6251755d92489ef685af8d4ff3eb
+RUN --mount=type=cache,id=gocache,target=/root/.cache/go-build set -x \
+	&& export GOPATH="$(mktemp -d)" \
+	&& git clone https://github.com/go-swagger/go-swagger.git "$GOPATH/src/github.com/go-swagger/go-swagger" \
+	&& (cd "$GOPATH/src/github.com/go-swagger/go-swagger" && git checkout -q "$GO_SWAGGER_COMMIT") \
+	&& go build -o /build/swagger github.com/go-swagger/go-swagger/cmd/swagger \
+	&& rm -rf "$GOPATH"
+
+
+FROM base AS frozen-images
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+		apt-get update && apt-get install -y jq ca-certificates --no-install-recommends
+# Get useful and necessary Hub images so we can "docker load" locally instead of pulling
+COPY contrib/download-frozen-image-v2.sh /
+RUN /download-frozen-image-v2.sh /build \
+	buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \
+	busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \
+	busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \
+	debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
+	hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
+# See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list)
+
+FROM base AS cross-false
+
+FROM base AS cross-true
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+		dpkg --add-architecture armhf \
+		&& dpkg --add-architecture arm64 \
+		&& dpkg --add-architecture armel
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+		if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
+		apt-get update \
+		&& apt-get install -y --no-install-recommends \
+			crossbuild-essential-armhf \
+			crossbuild-essential-arm64 \
+			crossbuild-essential-armel; \
+		fi
+
+FROM cross-${CROSS} as dev-base
+
+FROM dev-base AS runtime-dev-cross-false
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+		apt-get update && apt-get install -y \
+			libapparmor-dev \
+			libseccomp-dev
+
+FROM cross-true AS runtime-dev-cross-true
+# These crossbuild packages rely on gcc-<arch>, but this doesn't want to install
+# on non-amd64 systems.
+# Additionally, the crossbuild-amd64 is currently only on debian:buster, so
+# other architectures cannnot crossbuild amd64.
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+		if [ "$(go env GOHOSTARCH)" = "amd64" ]; then \
+			apt-get update \
+			&& apt-get install -y \
+				libseccomp-dev:armhf \
+				libseccomp-dev:arm64 \
+				libseccomp-dev:armel \
+				libapparmor-dev:armhf \
+				libapparmor-dev:arm64 \
+				libapparmor-dev:armel \
+				# install this arches seccomp here due to compat issues with the v0 builder
+				# This is as opposed to inheriting from runtime-dev-cross-false
+				libapparmor-dev \
+				libseccomp-dev; \
+		fi
+
+FROM runtime-dev-cross-${CROSS} AS runtime-dev
+
+FROM base AS tomlv
+ENV INSTALL_BINARY_NAME=tomlv
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM base AS vndr
+ENV INSTALL_BINARY_NAME=vndr
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM dev-base AS containerd
+RUN apt-get update && apt-get install -y btrfs-tools
+ENV INSTALL_BINARY_NAME=containerd
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM dev-base AS proxy
+ENV INSTALL_BINARY_NAME=proxy
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM base AS gometalinter
+ENV INSTALL_BINARY_NAME=gometalinter
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM dev-base AS dockercli
+ENV INSTALL_BINARY_NAME=dockercli
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM runtime-dev AS runc
+ENV INSTALL_BINARY_NAME=runc
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM dev-base AS tini
+RUN apt-get update && apt-get install -y cmake vim-common
+COPY hack/dockerfile/install/install.sh ./install.sh
+ENV INSTALL_BINARY_NAME=tini
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build ./install.sh $INSTALL_BINARY_NAME
+
+FROM dev-base AS rootlesskit
+ENV INSTALL_BINARY_NAME=rootlesskit
+COPY hack/dockerfile/install/install.sh ./install.sh
+COPY hack/dockerfile/install/$INSTALL_BINARY_NAME.installer ./
+RUN  --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	PREFIX=/build/ ./install.sh $INSTALL_BINARY_NAME
+COPY ./contrib/dockerd-rootless.sh /build
+
+# TODO: Some of this is only really needed for testing, it would be nice to split this up
+FROM runtime-dev AS dev
+RUN groupadd -r docker
+RUN useradd --create-home --gid docker unprivilegeduser
+# Let us use a .bashrc file
+RUN ln -sfv /go/src/github.com/docker/docker/.bashrc ~/.bashrc
+# Activate bash completion and include Docker's completion if mounted with DOCKER_BASH_COMPLETION_PATH
+RUN echo "source /usr/share/bash-completion/bash_completion" >> /etc/bash.bashrc
+RUN ln -s /usr/local/completion/bash/docker /etc/bash_completion.d/docker
+RUN ldconfig
+# This should only install packages that are specifically needed for the dev environment and nothing else
+# Do you really need to add another package here? Can it be done in a different build stage?
+RUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=private \
+	--mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=private \
+apt-get update && apt-get install -y \
+	apparmor \
+	aufs-tools \
+	bash-completion \
+	btrfs-tools \
+	iptables \
+	jq \
+	libcap2-bin \
+	libdevmapper-dev \
+# libffi-dev and libssl-dev appear to be required for compiling paramiko on s390x/ppc64le
+	libffi-dev \
+	libssl-dev \
+	libudev-dev \
+	libsystemd-dev \
+	binutils-mingw-w64 \
+	g++-mingw-w64-x86-64 \
+	net-tools \
+	pigz \
+	python-backports.ssl-match-hostname \
+	python-dev \
+# python-cffi appears to be required for compiling paramiko on s390x/ppc64le
+	python-cffi \
+	python-mock \
+	python-pip \
+	python-requests \
+	python-setuptools \
+	python-websocket \
+	python-wheel \
+	thin-provisioning-tools \
+	vim \
+	vim-common \
+	xfsprogs \
+	zip \
+	bzip2 \
+	xz-utils \
+	libprotobuf-c1 \
+	libnet1 \
+	libnl-3-200 \
+	--no-install-recommends
+COPY --from=swagger /build/swagger* /usr/local/bin/
+COPY --from=frozen-images /build/ /docker-frozen-images
+COPY --from=gometalinter /build/ /usr/local/bin/
+COPY --from=tomlv /build/ /usr/local/bin/
+COPY --from=vndr /build/ /usr/local/bin/
+COPY --from=tini /build/ /usr/local/bin/
+COPY --from=runc /build/ /usr/local/bin/
+COPY --from=containerd /build/ /usr/local/bin/
+COPY --from=proxy /build/ /usr/local/bin/
+COPY --from=dockercli /build/ /usr/local/cli
+COPY --from=registry /build/registry* /usr/local/bin/
+COPY --from=criu /build/ /usr/local/
+COPY --from=docker-py /build/ /docker-py
+COPY --from=rootlesskit /build/ /usr/local/bin/
+COPY --from=djs55/vpnkit@sha256:e508a17cfacc8fd39261d5b4e397df2b953690da577e2c987a47630cd0c42f8e /vpnkit /usr/local/bin/vpnkit.x86_64
+
+ENV PATH=/usr/local/cli:$PATH
+ENV DOCKER_BUILDTAGS apparmor seccomp selinux
+# Options for hack/validate/gometalinter
+ENV GOMETALINTER_OPTS="--deadline=2m"
+WORKDIR /go/src/github.com/docker/docker
+VOLUME /var/lib/docker
+# Wrap all commands in the "docker-in-docker" script to allow nested containers
+ENTRYPOINT ["hack/dind"]
+
+FROM dev AS final
+# Upload docker source
+COPY . /go/src/github.com/docker/docker
+ARG DOCKER_GITCOMMIT=HEAD
+RUN --mount=type=cache,id=gocache,target=/root/.cache/go-build \
+	hack/make.sh binary
+RUN hack/make.sh install-binary