Support reproducible builds (except packages)

See docker-library/official-images issue 16044

- `SOURCE_DATE_EPOCH` is added.
  The value is consumed by the build scripts to make the `httpd` binary reproducible.

- GNU implementation of `wget` is executed with `--no-hsts` to disable creating `/root/.wget-hsts`

- For Debian, `/var/log/*` is removed as they contain timestamps

- For Debian, `/var/cache/ldconfig/aux-cache` is removed as they contain inode numbers, etc.

- For Alpine, virtual package versions are pinned to "0" to eliminate
  the timestamp-based version numbers that appear in `/etc/apk/world` and `/lib/apk/db/installed`

> [!NOTE]
> The following topics are NOT covered by this commit:
>
> - To reproduce file timestamps in layers, BuildKit has to be executed with
>   `--output type=<TYPE>,rewrite-timestamp=true`.
>   Needs BuildKit v0.13 or later.
>
> - To reproduce the base image by the hash, reproducers may:
>   - modify the `FROM` instruction in Dockerfile manually
>   - or, use the `CONVERT` action of source policies to replace the base image.
>     <https://github.com/moby/buildkit/blob/v0.13.2/docs/build-repro.md>
>
> - To reproduce packages, see the `RUN` instruction hook proposed in
>   moby/buildkit PR 4576

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda 2024-01-22 18:56:13 +09:00
parent bebe68a7d5
commit cd821bee3e
No known key found for this signature in database
GPG Key ID: 49524C6F9F638F1A
2 changed files with 27 additions and 7 deletions

View File

@ -1,5 +1,9 @@
FROM debian:bookworm-slim
# The global SOURCE_DATE_EPOCH is consumed by commands that are not associated with a source artifact.
# This is not propagated from --build-arg: https://github.com/moby/buildkit/issues/4576#issuecomment-2159501282
ENV SOURCE_DATE_EPOCH 0
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
#RUN groupadd -r www-data && useradd -r --create-home -g www-data www-data
@ -20,7 +24,9 @@ RUN set -eux; \
# https://github.com/docker-library/httpd/issues/209
libldap-common \
; \
rm -rf /var/lib/apt/lists/*
rm -rf /var/lib/apt/lists/* ; \
# clean up for reproducibility
rm -rf /var/log/* /var/cache/ldconfig/aux-cache
ENV HTTPD_VERSION 2.4.62
ENV HTTPD_SHA256 674188e7bf44ced82da8db522da946849e22080d73d16c93f7f4df89e25729ec
@ -68,7 +74,7 @@ RUN set -eux; \
# if the version is outdated, we have to pull from the archive
https://archive.apache.org/dist/ \
; do \
if wget -O "$f" "$distUrl$distFile" && [ -s "$f" ]; then \
if wget --no-hsts -O "$f" "$distUrl$distFile" && [ -s "$f" ]; then \
success=1; \
break; \
fi; \
@ -170,7 +176,7 @@ RUN set -eux; \
local patchSha256="$1"; shift; \
ddist "$patchFile" "httpd/patches/apply_to_$HTTPD_VERSION/$patchFile"; \
echo "$patchSha256 *$patchFile" | sha256sum -c -; \
patch -p0 < "$patchFile"; \
patch --set-utc --force -p0 < "$patchFile"; \
rm -f "$patchFile"; \
done; \
}; \
@ -180,6 +186,10 @@ RUN set -eux; \
CFLAGS="$(dpkg-buildflags --get CFLAGS)"; \
CPPFLAGS="$(dpkg-buildflags --get CPPFLAGS)"; \
LDFLAGS="$(dpkg-buildflags --get LDFLAGS)"; \
SOURCE_DATE_EPOCH="$(find . -type f -exec stat -c '%Y' {} + | sort -nr | head -n1)"; \
export SOURCE_DATE_EPOCH; \
# for logging validation/edification
date --date "@$SOURCE_DATE_EPOCH" --rfc-2822; \
./configure \
--build="$gnuArch" \
--prefix="$HTTPD_PREFIX" \
@ -225,7 +235,9 @@ RUN set -eux; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
\
# smoke test
httpd -v
httpd -v; \
# clean up for reproducibility
rm -rf /var/log/* /var/cache/ldconfig/aux-cache
# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop
STOPSIGNAL SIGWINCH

View File

@ -1,5 +1,9 @@
FROM alpine:3.20
# The global SOURCE_DATE_EPOCH is consumed by commands that are not associated with a source artifact.
# This is not propagated from --build-arg: https://github.com/moby/buildkit/issues/4576#issuecomment-2159501282
ENV SOURCE_DATE_EPOCH 0
# ensure www-data user exists
RUN set -x \
&& adduser -u 82 -D -S -G www-data www-data
@ -35,7 +39,7 @@ ENV HTTPD_PATCHES=""
# see https://httpd.apache.org/docs/2.4/install.html#requirements
RUN set -eux; \
\
apk add --no-cache --virtual .build-deps \
apk add --no-cache --virtual .build-deps=0 \
apr-dev \
apr-util-dev \
coreutils \
@ -181,13 +185,17 @@ RUN set -eux; \
local patchSha256="$1"; shift; \
ddist "$patchFile" "httpd/patches/apply_to_$HTTPD_VERSION/$patchFile"; \
echo "$patchSha256 *$patchFile" | sha256sum -c -; \
patch -p0 < "$patchFile"; \
patch --set-utc --force -p0 < "$patchFile"; \
rm -f "$patchFile"; \
done; \
}; \
patches $HTTPD_PATCHES; \
\
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
SOURCE_DATE_EPOCH="$(find . -type f -exec stat -c '%Y' {} + | sort -nr | head -n1)"; \
export SOURCE_DATE_EPOCH; \
# for logging validation/edification
date --date "@$SOURCE_DATE_EPOCH" --rfc-2822; \
./configure \
--build="$gnuArch" \
--prefix="$HTTPD_PREFIX" \
@ -219,7 +227,7 @@ RUN set -eux; \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-network --virtual .httpd-so-deps $deps; \
apk add --no-network --virtual .httpd-so-deps=0 $deps; \
apk del --no-network .build-deps; \
\
# smoke test