Status of bit-for-bit reproducible Docker/OCI images (and FOSDEM talk on Sat 12:55)
Akihiro Suda
suda.kyoto at gmail.com
Thu Feb 2 01:40:33 UTC 2023
Hi there, let me just share the latest status of reproducible Docker/OCI
container image builds with BuildKit: https://github.com/moby/buildkit
(OCI = "Open Container Initiative", not "Oracle Cloud Infrastructure")
BuildKit v0.11 was released in the last month with very preliminary support
for SOURCE_DATE_EPOCH and bit-for-bit reproducible builds:
```dockerfile
FROM debian:bullseye-20230109
ARG SOURCE_DATE_EPOCH
RUN echo "hello ${SOURCE_DATE_EPOCH}" >/hello
# === Workarounds below will not be needed when
https://github.com/moby/buildkit/pull/3560 is merged ===
# Limit the timestamp upper bound to SOURCE_DATE_EPOCH.
# Workaround for https://github.com/moby/buildkit/issues/3180
RUN find $( ls / | grep -E -v "^(dev|mnt|proc|sys)$" ) -newermt
"@${SOURCE_DATE_EPOCH}" -writable -xdev | xargs touch
--date="@${SOURCE_DATE_EPOCH}" --no-dereference
# Squash the entire stage for resetting the whiteout timestamps.
# Workaround for https://github.com/moby/buildkit/issues/3168
FROM scratch
COPY --from=0 / /
```
Currently, the SOURCE_DATE_EPOCH value is only applied to the timestamps in
the image metadata (e.g., the `docker history` timestamps), but not
automatically applied to the timestamps of the layered files.
So, BuildKit v0.11 still requires a very complex Dockerfile, but this will
be significantly simplified when https://github.com/moby/buildkit/pull/3560
gets merged.
The above Dockerfile can be deterministically built with the following
commands:
```bash
# Make sure to pin the BuildKit version
docker run -d --name buildkitd --privileged --restart=always
moby/buildkit:v0.11.0
docker cp buildkitd:/usr/bin/buildctl /usr/local/bin/buildctl
export BUILDKIT_HOST=docker-container://buildkitd
SOURCE_DATE_EPOCH=1675298208
# Change to "true" for pushing the image to the registry
PUSH=false
buildctl build \
--frontend dockerfile.v0 \
--local dockerfile=. \
--local context=. \
--metadata-file metadata.json \
--output type=image,name=
example.com/foo:$SOURCE_DATE_EPOCH,buildinfo=false,push=$PUSH \
--opt build-arg:SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH
# Verify the image digest
[ "$(jq -r '."containerimage.digest"' < metadata.json)" =
"sha256:b313cd9751ed3e0c3f7185c034fde857302d56642ac5518f1ebbf7fc2e8eed93" ]
```
Note that the buildctl CLI does not automatically propagate the
$SOURCE_DATE_EPOCH env var to containers. (While the buildx CLI does.)
So, the `--opt build-arg:SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH` flag is
explicitly required.
I'll talk further about this at FOSDEM:
https://fosdem.org/2023/schedule/event/container_reproducible_dockerfile/
(Sat 12:55-13:15, Containers devroom, UB2.252A (Lameere))
My talk will also mention how to pin the apt/dnf/apk/pacman packages with
my "repro-get" tool ( https://github.com/reproducible-containers/repro-get
).
Looking forward to meeting you all at FOSDEM.
Regards,
Akihiro Suda
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.reproducible-builds.org/pipermail/rb-general/attachments/20230202/ce52eb43/attachment.htm>
More information about the rb-general
mailing list