Skip to content

Commit

Permalink
Support reproducible builds (except packages)
Browse files Browse the repository at this point in the history
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`

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.0-beta1 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.0-beta1/docs/build-repro.md>

- To reproduce Debian packages, reproducers may:
  - modify the `RUN` instructions in the Dockerfile to rewrite `/etc/apt/sources.list`
    to use <http://snapshot.debian.org>, and restore `/etc/apt/sources.list`
    at the end of the instruction (See the rejected PR 248)
  - or, specify a custom Dockerfile frontend implementation that
    rewrites/restores `/etc/apt/sources.list`
  - or, specify a custom `HTTP_PROXY` that redirects HTTP requests for
    <http://deb.debian.org> to <http://snapshot.debian.org>.
    This is less reliable in long-term due to `Acquire::Check-Valid-Until`.

Signed-off-by: Akihiro Suda <[email protected]>
  • Loading branch information
AkihiroSuda committed Jun 11, 2024
1 parent 02a2b56 commit c5d365c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
20 changes: 16 additions & 4 deletions 2.4/Dockerfile
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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.59
ENV HTTPD_SHA256 ec51501ec480284ff52f637258135d333230a7d229c3afa6f6c2f9040e321323
Expand Down Expand Up @@ -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; \
Expand Down Expand Up @@ -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; \
}; \
Expand All @@ -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" \
Expand Down Expand Up @@ -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
Expand Down
14 changes: 11 additions & 3 deletions 2.4/alpine/Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -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" \
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c5d365c

Please sign in to comment.