# syntax=docker/dockerfile:1 ARG GO_VERSION=1.25.5 ARG BASE_DEBIAN_DISTRO="bookworm" ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}" # XX_VERSION specifies the version of the xx utility to use. # It must be a valid tag in the docker.io/tonistiigi/xx image repository. ARG XX_VERSION=1.7.0 # VPNKIT_VERSION is the version of the vpnkit binary which is used as a fallback # network driver for rootless. ARG VPNKIT_VERSION=0.6.0 # DOCKERCLI_VERSION is the version of the CLI to install in the dev-container. ARG DOCKERCLI_VERSION=v29.1.2 ARG DOCKERCLI_REPOSITORY="https://github.com/docker/cli.git" # cli version used for integration-cli tests ARG DOCKERCLI_INTEGRATION_REPOSITORY="https://github.com/docker/cli.git" ARG DOCKERCLI_INTEGRATION_VERSION=v25.0.5 # BUILDX_VERSION is the version of buildx to install in the dev container. ARG BUILDX_VERSION=0.30.1 # COMPOSE_VERSION is the version of compose to install in the dev container. ARG COMPOSE_VERSION=v5.0.0 ARG SYSTEMD="false" ARG FIREWALLD="false" ARG DOCKER_STATIC=1 # REGISTRY_VERSION specifies the version of the registry to download from # https://hub.docker.com/r/distribution/distribution. This version of # the registry is used to test schema 2 manifests. Generally, the version # specified here should match a current release. ARG REGISTRY_VERSION=3.0.0 # delve is currently only supported on linux/amd64 and linux/arm64; # https://github.com/go-delve/delve/blob/v1.25.0/pkg/proc/native/support_sentinel.go#L1 # https://github.com/go-delve/delve/blob/v1.25.0/pkg/proc/native/support_sentinel_linux.go#L1 # # ppc64le support was added in v1.21.1, but is still experimental, and requires # the "-tags exp.linuxppc64le" build-tag to be set: # https://github.com/go-delve/delve/commit/71f12207175a1cc09668f856340d8a543c87dcca ARG DELVE_SUPPORTED=${TARGETPLATFORM#linux/amd64} DELVE_SUPPORTED=${DELVE_SUPPORTED#linux/arm64} DELVE_SUPPORTED=${DELVE_SUPPORTED#linux/ppc64le} ARG DELVE_SUPPORTED=${DELVE_SUPPORTED:+"unsupported"} ARG DELVE_SUPPORTED=${DELVE_SUPPORTED:-"supported"} # cross compilation helper FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx # dummy stage to make sure the image is built for deps that don't support some # architectures FROM --platform=$BUILDPLATFORM busybox AS build-dummy RUN mkdir -p /build FROM scratch AS binary-dummy COPY --from=build-dummy /build /build # base FROM --platform=$BUILDPLATFORM ${GOLANG_IMAGE} AS base COPY --from=xx / / # Disable collecting local telemetry, as collected by Go and Delve; # # - https://github.com/go-delve/delve/blob/v1.24.1/CHANGELOG.md#1231-2024-09-23 # - https://go.dev/doc/telemetry#background RUN go telemetry off && [ "$(go telemetry)" = "off" ] || { echo "Failed to disable Go telemetry"; exit 1; } RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache RUN apt-get update && apt-get install --no-install-recommends -y file ENV GOTOOLCHAIN=local FROM base AS criu ADD --chmod=0644 https://download.opensuse.org/repositories/devel:/tools:/criu/Debian_11/Release.key /etc/apt/trusted.gpg.d/criu.gpg.asc 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 \ echo 'deb https://download.opensuse.org/repositories/devel:/tools:/criu/Debian_12/ /' > /etc/apt/sources.list.d/criu.list \ && apt-get update \ && apt-get install -y --no-install-recommends criu \ && install -D /usr/sbin/criu /build/criu \ && /build/criu --version # registry FROM distribution/distribution:$REGISTRY_VERSION AS registry RUN mkdir /build && mv /bin/registry /build/registry # frozen-images # See also frozenImages in "testutil/environment/protect.go" (which needs to # be updated when adding images to this list) FROM debian:${BASE_DEBIAN_DISTRO} AS frozen-images 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 \ curl \ jq # Get useful and necessary Hub images so we can "docker load" locally instead of pulling COPY contrib/download-frozen-image-v2.sh / ARG TARGETARCH ARG TARGETVARIANT RUN /download-frozen-image-v2.sh /build \ busybox:latest@sha256:95cf004f559831017cdf4628aaf1bb30133677be8702a8c5f2994629f637a209 \ busybox:glibc@sha256:1f81263701cddf6402afe9f33fca0266d9fff379e59b1748f33d3072da71ee85 \ debian:trixie-slim@sha256:c85a2732e97694ea77237c61304b3bb410e0e961dd6ee945997a06c788c545bb \ hello-world:latest@sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9 \ arm32v7/hello-world:latest@sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1 \ hello-world:amd64@sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 \ hello-world:arm64@sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343 # delve FROM base AS delve-src WORKDIR /usr/src/delve RUN git init . && git remote add origin "https://github.com/go-delve/delve.git" # DELVE_VERSION specifies the version of the Delve debugger binary # from the https://github.com/go-delve/delve repository. # It can be used to run Docker with a possibility of # attaching debugger to it. ARG DELVE_VERSION=v1.25.2 RUN git fetch -q --depth 1 origin "${DELVE_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD FROM base AS delve-supported WORKDIR /usr/src/delve ARG TARGETPLATFORM RUN --mount=from=delve-src,src=/usr/src/delve,rw \ --mount=type=cache,target=/root/.cache/go-build,id=delve-build-$TARGETPLATFORM \ --mount=type=cache,target=/go/pkg/mod </completion.bash FROM base AS dockercli-integration WORKDIR /go/src/github.com/docker/cli ARG DOCKERCLI_INTEGRATION_REPOSITORY ARG DOCKERCLI_INTEGRATION_VERSION ARG TARGETPLATFORM RUN --mount=source=hack/dockerfile/cli.sh,target=/download-or-build-cli.sh \ --mount=type=cache,id=dockercli-git-$TARGETPLATFORM,sharing=locked,target=./.git \ --mount=type=cache,target=/root/.cache/go-build,id=dockercli-build-$TARGETPLATFORM \ rm -f ./.git/*.lock \ && /download-or-build-cli.sh ${DOCKERCLI_INTEGRATION_VERSION} ${DOCKERCLI_INTEGRATION_REPOSITORY} /build \ && /build/docker --version # runc FROM base AS runc-src WORKDIR /usr/src/runc RUN git init . && git remote add origin "https://github.com/opencontainers/runc.git" # RUNC_VERSION sets the version of runc to install in the dev-container. # This version should usually match the version that is used by the containerd version # that is used. If you need to update runc, open a pull request in the containerd # project first, and update both after that is merged. ARG RUNC_VERSION=v1.3.4 RUN git fetch -q --depth 1 origin "${RUNC_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD FROM base AS runc-build WORKDIR /go/src/github.com/opencontainers/runc ARG TARGETPLATFORM RUN --mount=type=cache,sharing=locked,id=moby-runc-aptlib,target=/var/lib/apt \ --mount=type=cache,sharing=locked,id=moby-runc-aptcache,target=/var/cache/apt \ apt-get update && xx-apt-get install -y --no-install-recommends \ gcc \ libc6-dev \ libseccomp-dev \ pkg-config ARG DOCKER_STATIC RUN --mount=from=runc-src,src=/usr/src/runc,rw \ --mount=type=cache,target=/root/.cache/go-build,id=runc-build-$TARGETPLATFORM <> /etc/bash.bashrc RUN ldconfig # Set dev environment as safe git directory to prevent "dubious ownership" errors # when bind-mounting the source into the dev-container. See https://github.com/moby/moby/pull/44930 RUN git config --global --add safe.directory $GOPATH/src/github.com/docker/docker # 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,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 \ bash-completion \ bzip2 \ fuse-overlayfs \ inetutils-ping \ iproute2 \ iptables \ nftables \ jq \ libcap2-bin \ libnet1 \ libnftables-dev \ libnl-3-200 \ libprotobuf-c1 \ libyajl2 \ nano \ net-tools \ netcat-openbsd \ patch \ pigz \ sudo \ systemd-journal-remote \ thin-provisioning-tools \ uidmap \ vim \ vim-common \ xfsprogs \ xz-utils \ zip \ zstd 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 --no-install-recommends -y \ gcc \ pkg-config \ libseccomp-dev \ libsystemd-dev \ yamllint COPY --link --from=dockercli /build/ /usr/local/cli COPY --link --from=dockercli /completion.bash /etc/bash_completion.d/docker COPY --link --from=dockercli-integration /build/ /usr/local/cli-integration FROM base AS build COPY --from=gowinres /build/ /usr/local/bin/ WORKDIR /go/src/github.com/docker/docker ENV CGO_ENABLED=1 RUN --mount=type=cache,sharing=locked,id=moby-build-aptlib,target=/var/lib/apt \ --mount=type=cache,sharing=locked,id=moby-build-aptcache,target=/var/cache/apt \ apt-get update && apt-get install --no-install-recommends -y \ clang \ lld \ llvm \ icoutils ARG TARGETPLATFORM RUN --mount=type=cache,sharing=locked,id=moby-build-aptlib,target=/var/lib/apt \ --mount=type=cache,sharing=locked,id=moby-build-aptcache,target=/var/cache/apt \ xx-apt-get install --no-install-recommends -y \ gcc \ libc6-dev \ libnftables-dev \ libseccomp-dev \ libsystemd-dev \ pkg-config ARG DOCKER_BUILDTAGS ARG DOCKER_DEBUG ARG DOCKER_GITCOMMIT=HEAD ARG DOCKER_LDFLAGS ARG DOCKER_STATIC ARG VERSION ARG PLATFORM ARG PRODUCT ARG DEFAULT_PRODUCT_LICENSE ARG PACKAGER_NAME # PREFIX overrides DEST dir in make.sh script otherwise it fails because of # read only mount in current work dir ENV PREFIX=/tmp RUN < docker buildx bake binary # > DOCKER_STATIC=0 docker buildx bake binary # or # > make binary # > make dynbinary FROM scratch AS binary COPY --from=build /build/ / # usage: # > docker buildx bake all FROM scratch AS all COPY --link --from=tini /build/ / COPY --link --from=runc /build/ / COPY --link --from=containerd /build/ / COPY --link --from=rootlesskit /build/ / COPY --link --from=containerutil /build/ / COPY --link --from=vpnkit / / COPY --link --from=build /build / # smoke tests # usage: # > docker buildx bake binary-smoketest FROM base AS smoketest WORKDIR /usr/local/bin COPY --from=build /build . RUN < docker buildx bake dind # > docker run -d --restart always --privileged --name devdind -p 12375:2375 docker-dind --debug --host=tcp://0.0.0.0:2375 --tlsverify=false FROM docker:dind AS dind COPY --link --from=dockercli /build/docker /usr/local/bin/ COPY --link --from=buildx /buildx /usr/local/libexec/docker/cli-plugins/docker-buildx COPY --link --from=compose /docker-compose /usr/local/libexec/docker/cli-plugins/docker-compose COPY --link --from=all / /usr/local/bin/ # usage: # > make shell # > SYSTEMD=true make shell FROM dev-base AS dev COPY --link . .