# syntax=docker/dockerfile:1 ARG GO_VERSION=1.25.4 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.0.1 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.29.1 # COMPOSE_VERSION is the version of compose to install in the dev container. ARG COMPOSE_VERSION=v2.40.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 # go-swagger FROM base AS swagger WORKDIR /go/src/github.com/go-swagger/go-swagger ARG TARGETPLATFORM # GO_SWAGGER_VERSION specifies the version of the go-swagger binary to install. # Go-swagger is used in CI for generating types from swagger.yaml in # hack/validate/swagger-gen ARG GO_SWAGGER_VERSION=v0.33.1 RUN --mount=type=cache,target=/root/.cache/go-build,id=swagger-build-$TARGETPLATFORM \ --mount=type=cache,target=/go/pkg/mod \ --mount=type=tmpfs,target=/go/src/ </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.3 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 . .