# syntax=docker/dockerfile:1 ARG GO_VERSION=1.20.4 ARG BASE_DEBIAN_DISTRO="bullseye" ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}" ARG XX_VERSION=1.2.1 ARG VPNKIT_VERSION=0.5.0 ARG DOCKERCLI_VERSION=v17.06.2-ce ARG SYSTEMD="false" ARG DEBIAN_FRONTEND=noninteractive ARG DOCKER_STATIC=1 # 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 / / 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 ARG DEBIAN_FRONTEND RUN apt-get update && apt-get install --no-install-recommends -y file ENV GO111MODULE=off FROM base AS criu ARG DEBIAN_FRONTEND 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_11/ /' > /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 # registry FROM base AS registry-src WORKDIR /usr/src/registry RUN git init . && git remote add origin "https://github.com/distribution/distribution.git" FROM base AS registry WORKDIR /go/src/github.com/docker/distribution # REGISTRY_VERSION specifies the version of the registry to build and install # from the https://github.com/docker/distribution repository. This version of # the registry is used to test both schema 1 and schema 2 manifests. Generally, # the version specified here should match a current release. ARG REGISTRY_VERSION=v2.3.0 # REGISTRY_VERSION_SCHEMA1 specifies the version of the registry to build and # install from the https://github.com/docker/distribution repository. This is # an older (pre v2.3.0) version of the registry that only supports schema1 # manifests. This version of the registry is not working on arm64, so installation # is skipped on that architecture. ARG REGISTRY_VERSION_SCHEMA1=v2.1.0 ARG TARGETPLATFORM RUN --mount=from=registry-src,src=/usr/src/registry,rw \ --mount=type=cache,target=/root/.cache/go-build,id=registry-build-$TARGETPLATFORM \ --mount=type=cache,target=/go/pkg/mod \ --mount=type=tmpfs,target=/go/src </dev/null 2>&1; then mkdir /build curl -Ls "${DOWNLOAD_URL}" | tar -xz docker/docker mv docker/docker /build/docker else CGO_ENABLED=0 xx-go build -o /build/docker ./cmd/docker fi xx-verify /build/docker EOT # 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 should 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. When updating RUNC_VERSION, # consider updating runc in vendor.mod accordingly. ARG RUNC_VERSION=v1.1.7 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 DEBIAN_FRONTEND 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 \ dpkg-dev gcc libc6-dev libseccomp-dev 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 ln -s /usr/local/completion/bash/docker /etc/bash_completion.d/docker 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 \ inetutils-ping \ iproute2 \ iptables \ jq \ libcap2-bin \ libnet1 \ libnl-3-200 \ libprotobuf-c1 \ libyajl2 \ net-tools \ patch \ pigz \ python3-pip \ python3-setuptools \ python3-wheel \ sudo \ systemd-journal-remote \ thin-provisioning-tools \ uidmap \ vim \ vim-common \ xfsprogs \ xz-utils \ zip \ zstd # Switch to use iptables instead of nftables (to match the CI hosts) # TODO use some kind of runtime auto-detection instead if/when nftables is supported (https://github.com/moby/moby/issues/26824) RUN update-alternatives --set iptables /usr/sbin/iptables-legacy || true \ && update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy || true \ && update-alternatives --set arptables /usr/sbin/arptables-legacy || true ARG YAMLLINT_VERSION=1.27.1 RUN pip3 install yamllint==${YAMLLINT_VERSION} 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 \ dpkg-dev \ libapparmor-dev \ libdevmapper-dev \ libseccomp-dev \ libsecret-1-dev \ libsystemd-dev \ libudev-dev FROM base AS build COPY --from=gowinres /build/ /usr/local/bin/ WORKDIR /go/src/github.com/docker/docker ENV GO111MODULE=off ENV CGO_ENABLED=1 ARG DEBIAN_FRONTEND 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 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 \ dpkg-dev \ gcc \ libapparmor-dev \ libc6-dev \ libdevmapper-dev \ libseccomp-dev \ libsecret-1-dev \ libsystemd-dev \ libudev-dev 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 --from=tini /build/ / COPY --from=runc /build/ / COPY --from=containerd /build/ / COPY --from=rootlesskit /build/ / COPY --from=containerutil /build/ / COPY --from=vpnkit / / COPY --from=build /build / # smoke tests # usage: # > docker buildx bake binary-smoketest FROM --platform=$TARGETPLATFORM base AS smoketest WORKDIR /usr/local/bin COPY --from=build /build . RUN < make shell # > SYSTEMD=true make shell FROM dev-base AS dev COPY . .