Skip to content

Commit

Permalink
Dockerfile: add ALPINE_CACHE image to lock apk versions
Browse files Browse the repository at this point in the history
The `ALPINE_CACHE` image contains `/etc/apk/cache` for apk files
referred from the entire Dockerfile.

All the `apk add` commands in the Dockerfile are now executed with
the mount for `ALPINE_CACHE` and with `--no-network`.

The `ALPINE_CACHE` image defaults to the `alpine-cache-local` stage,
but can be also set to `docker.io/moby/buildkit:${RELEASE}-alpine-cache`
for reproducibility.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Sep 15, 2023
1 parent 02eecc6 commit 0cbda2e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 14 deletions.
1 change: 1 addition & 0 deletions .github/workflows/buildkit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ jobs:
target-stage:
- ''
- rootless
- alpine-cache
steps:
-
name: Checkout
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/buildx-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
flavor:
- ''
- 'rootless'
- 'alpine-cache'
steps:
-
name: Set up Docker Buildx
Expand Down
83 changes: 69 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,82 @@ ARG GOTESTSUM_VERSION=v1.9.0
ARG GO_VERSION=1.20
ARG ALPINE_VERSION=3.18

# ALPINE_CACHE defaults to the "alpine-cache-local" stage in this image.
# Can be overridden to a custom image for reproducible builds.
ARG ALPINE_CACHE=alpine-cache-local

# minio for s3 integration tests
FROM minio/minio:${MINIO_VERSION} AS minio
FROM minio/mc:${MINIO_MC_VERSION} AS minio-mc

# alpine base for buildkit image
# TODO: remove this when alpine image supports riscv64
FROM alpine:${ALPINE_VERSION} AS alpine-amd64
FROM alpine:${ALPINE_VERSION} AS alpine-arm
FROM alpine:${ALPINE_VERSION} AS alpine-arm64
FROM alpine:${ALPINE_VERSION} AS alpine-s390x
FROM alpine:${ALPINE_VERSION} AS alpine-ppc64le
FROM alpine:edge@sha256:2d01a16bab53a8405876cec4c27235d47455a7b72b75334c614f2fb0968b3f90 AS alpine-riscv64
FROM --platform=amd64 alpine:${ALPINE_VERSION} AS alpine-amd64
FROM --platform=arm alpine:${ALPINE_VERSION} AS alpine-arm
FROM --platform=arm64 alpine:${ALPINE_VERSION} AS alpine-arm64
FROM --platform=s390x alpine:${ALPINE_VERSION} AS alpine-s390x
FROM --platform=ppc64le alpine:${ALPINE_VERSION} AS alpine-ppc64le
FROM --platform=riscv64 alpine:edge@sha256:2d01a16bab53a8405876cec4c27235d47455a7b72b75334c614f2fb0968b3f90 AS alpine-riscv64
FROM alpine-$TARGETARCH AS alpinebase
FROM --platform=$BUILDPLATFORM alpine AS alpinebase-buildplatform

# xx is a helper for cross-compilation
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.2.1 AS xx

FROM alpinebase AS alpine-cache-local-targetplatform
RUN --mount=source=./apklist,target=/apklist \
mkdir -p /etc/apk/cache && apk update && apk cache download --available --add-dependencies $(grep -v '^#' /apklist)

FROM alpinebase-buildplatform AS alpine-cache-local-buildplatform
RUN --mount=source=./apklist,target=/apklist \
mkdir -p /etc/apk/cache && apk update && apk cache download --available --add-dependencies $(grep -v '^#' /apklist)

FROM scratch AS alpine-cache-local
COPY --from=alpine-cache-local-targetplatform /etc/apk/cache /etc/apk/cache

# alpine-cache is the stage to collect apk cache files.
# This stage can be pushed for sake of reproducible builds.
FROM $ALPINE_CACHE AS alpine-cache
FROM --platform=amd64 alpine-cache AS alpine-cache-amd64
FROM --platform=arm alpine-cache AS alpine-cache-arm
FROM --platform=arm64 alpine-cache AS alpine-cache-arm64
FROM --platform=s390x alpine-cache AS alpine-cache-s390x
FROM --platform=ppc64le alpine-cache AS alpine-cache-ppc64le
FROM --platform=riscv64 alpine-cache AS alpine-cache-riscv64
FROM --platform=$TARGETPLATFORM alpine-cache-${TARGETARCH} AS alpine-cache-targetplatform
# NOTE: when $ALPINE_CACHE is set to alpine-cache-local, alpine-cache-remote-buildplatform is invalid,
# as alpine-cache-${BUILDARCH} is built from the TARGETPLATFORM image
FROM --platform=$BUILDPLATFORM alpine-cache-${BUILDARCH} AS alpine-cache-remote-buildplatform

FROM --platform=$BUILDPLATFORM alpinebase-buildplatform AS alpine-cache-xx
ARG BUILDPLATFORM
COPY --link --from=alpine-cache-remote-buildplatform /etc/apk/cache /etc/apk/cache/_remote_buildplatform
COPY --link --from=alpine-cache-local-buildplatform /etc/apk/cache /etc/apk/cache/_local_buildplatform
ARG ALPINE_CACHE
RUN <<EOT
if [ "$ALPINE_CACHE" = "alpine-cache-local" ]; then
ln -sf /etc/apk/cache/_local_buildplatform/* /etc/apk/cache/
else
ln -sf /etc/apk/cache/_remote_buildplatform/* /etc/apk/cache/
fi
EOT
ARG TARGETPLATFORM
COPY --link --from=alpine-cache-targetplatform /etc/apk/cache /etc/apk/cache/_targetplatform
COPY --link --from=xx / /
RUN ln -s _targetplatform /etc/apk/cache/_$(xx-info pkg-arch)

# go base image
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS golatest

# git stage is used for checking out remote repository sources
FROM --platform=$BUILDPLATFORM alpine:${ALPINE_VERSION} AS git
RUN apk add --no-cache git
RUN --mount=from=alpine-cache-xx,source=/etc/apk/cache,target=/etc/apk/cache,rw \
apk add --no-network git

# gobuild is base stage for compiling go/cgo
FROM golatest AS gobuild-base
RUN apk add --no-cache file bash clang lld musl-dev pkgconfig git make
RUN --mount=from=alpine-cache-xx,source=/etc/apk/cache,target=/etc/apk/cache,rw \
apk add --no-network file bash clang lld musl-dev pkgconfig git make
COPY --link --from=xx / /

# runc source
Expand All @@ -61,7 +110,8 @@ WORKDIR $GOPATH/src/github.com/opencontainers/runc
ARG TARGETPLATFORM
# gcc is only installed for libgcc
# lld has issues building static binaries for ppc so prefer ld for it
RUN set -e; xx-apk add musl-dev gcc libseccomp-dev libseccomp-static; \
RUN --mount=from=alpine-cache-xx,source=/etc/apk/cache,target=/etc/apk/cache,rw \
set -e; xx-apk add --no-network musl-dev gcc libseccomp-dev libseccomp-static; \
[ "$(xx-info arch)" != "ppc64le" ] || XX_CC_PREFER_LINKER=ld xx-clang --setup-target-triple
RUN --mount=from=runc-src,src=/usr/src/runc,target=. --mount=target=/root/.cache,type=cache \
CGO_ENABLED=1 xx-go build -mod=vendor -ldflags '-extldflags -static' -tags 'apparmor seccomp netgo cgo static_build osusergo' -o /usr/bin/runc ./ && \
Expand Down Expand Up @@ -136,7 +186,8 @@ FROM scratch AS release
COPY --link --from=releaser /out/ /

FROM alpinebase AS buildkit-export
RUN apk add --no-cache fuse3 git openssh pigz xz \
RUN --mount=from=alpine-cache-targetplatform,source=/etc/apk/cache,target=/etc/apk/cache,rw \
apk add --no-network fuse3 git openssh pigz xz \
&& ln -s fusermount3 /usr/bin/fusermount
COPY --link examples/buildctl-daemonless/buildctl-daemonless.sh /usr/bin/
VOLUME /var/lib/buildkit
Expand All @@ -151,7 +202,8 @@ FROM gobuild-base AS containerd-base
WORKDIR /go/src/github.com/containerd/containerd
ARG TARGETPLATFORM
ENV CGO_ENABLED=1 BUILDTAGS=no_btrfs GO111MODULE=off
RUN xx-apk add musl-dev gcc && xx-go --wrap
RUN --mount=from=alpine-cache-xx,source=/etc/apk/cache,target=/etc/apk/cache,rw \
xx-apk add --no-network musl-dev gcc && xx-go --wrap

FROM containerd-base AS containerd
ARG CONTAINERD_VERSION
Expand Down Expand Up @@ -253,7 +305,8 @@ COPY --link --from=dnsname /usr/bin/dnsname /opt/cni/bin/

FROM buildkit-base AS integration-tests-base
ENV BUILDKIT_INTEGRATION_ROOTLESS_IDPAIR="1000:1000"
RUN apk add --no-cache shadow shadow-uidmap sudo vim iptables ip6tables dnsmasq fuse curl git-daemon openssh-client \
RUN --mount=from=alpine-cache-xx,source=/etc/apk/cache,target=/etc/apk/cache,rw \
apk add --no-network shadow shadow-uidmap sudo vim iptables ip6tables dnsmasq fuse curl git-daemon openssh-client \
&& useradd --create-home --home-dir /home/user --uid 1000 -s /bin/sh user \
&& echo "XDG_RUNTIME_DIR=/run/user/1000; export XDG_RUNTIME_DIR" >> /home/user/.profile \
&& mkdir -m 0700 -p /run/user/1000 \
Expand All @@ -264,7 +317,8 @@ ARG NERDCTL_VERSION
RUN curl -Ls https://raw.githubusercontent.com/containerd/nerdctl/$NERDCTL_VERSION/extras/rootless/containerd-rootless.sh > /usr/bin/containerd-rootless.sh \
&& chmod 0755 /usr/bin/containerd-rootless.sh
ARG AZURITE_VERSION
RUN apk add --no-cache nodejs npm \
RUN --mount=from=alpine-cache-xx,source=/etc/apk/cache,target=/etc/apk/cache,rw \
apk add --no-network nodejs npm \
&& npm install -g azurite@${AZURITE_VERSION}
# The entrypoint script is needed for enabling nested cgroup v2 (https://github.com/moby/buildkit/issues/3265#issuecomment-1309631736)
RUN curl -Ls https://raw.githubusercontent.com/moby/moby/v20.10.21/hack/dind > /docker-entrypoint.sh \
Expand Down Expand Up @@ -301,7 +355,8 @@ VOLUME /var/lib/buildkit

# Rootless mode.
FROM alpinebase AS rootless
RUN apk add --no-cache fuse3 fuse-overlayfs git openssh pigz shadow-uidmap xz
RUN --mount=from=alpine-cache-targetplatform,source=/etc/apk/cache,target=/etc/apk/cache,rw \
apk add --no-network fuse3 fuse-overlayfs git openssh pigz shadow-uidmap xz
RUN adduser -D -u 1000 user \
&& mkdir -p /run/user/1000 /home/user/.local/tmp /home/user/.local/share/buildkit \
&& chown -R user /run/user/1000 /home/user \
Expand Down
33 changes: 33 additions & 0 deletions apklist
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# List of apks to be cached in moby/buildkit:${RELEASE}-alpine-cache for reproducibility
bash
clang
curl
dnsmasq
file
fuse
fuse3
fuse-overlayfs
gcc
git
git-daemon
gzip
iptables
ip6tables
libseccomp-dev
libseccomp-static
lld
make
musl-dev
nodejs
npm
openssh
openssh-client
pkgconfig
pigz
shadow
shadow-uidmap
sudo
tar
vim
xz
zlib
5 changes: 5 additions & 0 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ variable "ALPINE_VERSION" {
default = null
}

variable "ALPINE_CACHE" {
default = null
}

variable "GO_VERSION" {
default = null
}
Expand All @@ -26,6 +30,7 @@ function "bindir" {
target "_common" {
args = {
ALPINE_VERSION = ALPINE_VERSION
ALPINE_CACHE = ALPINE_CACHE
GO_VERSION = GO_VERSION
NODE_VERSION = NODE_VERSION
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
Expand Down

0 comments on commit 0cbda2e

Please sign in to comment.