buildkit
buildkit copied to clipboard
Add support for SOURCE_DATE_EPOCH
addresses #1058
Allows reproducible timestamps for layer and image timestamps.
Implemented as a frontend-opt because in the future, the same option could be detected by frontend for custom behavior
and the same value should also apply timestamps for FileOps. Definition for SOURCE_DATE_EPOCH
can be found in https://reproducible-builds.org/docs/source-date-epoch/
In local and tar exporter, setting the build-arg sets overwrites the timestamp for the output files.
There is also a secondary implementation inside the Dockerfile frontend. This allows getting reproducible image manifests even on old buildkit, by just defining #syntax
to point to new Dockerfile image.
In Dockerfiles the build-arg can also be exposed to inner processes by defining ARG SOURCE_DATE_EPOCH
inside the stage.
This is the first stop toward better reproducible builds support that can be followed up with:
- Overwrite timestamp for files created with FileOp, eg.
COPY/ADD
in Dockerfiles #2911 @AkihiroSuda - Possibly allow setting timestamp from Dockerfile, eg.
#epoch=
. Frontend side of this is already implemented and the frontend can pass the epoch value to the exporter(it can not overwrite the value if it has already been set by the user). - Add some special case that allows using setting epoch to git commit timestamp when building from git. Currently need to do
--build-arg SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
- Maybe allow configuring differ or overwriting files created by ExecOp
Can you update docs in https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#built-in-build-args for SOURCE_DATE_EPOCH
Can we pass this into the RUN steps without defining an ARG in the Dockerfile? I.e. the same way we do for http proxy today?
Can we pass this into the RUN steps without defining an ARG in the Dockerfile? I.e. the same way we do for http proxy today?
I think defining ARG
should be required. This changes the behavior of the RUN
and output of the created image so should be decision user makes. Proxy args are different because the expectation is that when two users are behind a different proxy they still generate the same image and proxy only affects their local network configuration and not the build result itself.
I think defining
ARG
should be required. This changes the behavior of theRUN
and output of the created image so should be decision user makes.
Since the user is running the build command, what if the forced ARG
was added to the steps even if not defined in the Dockerfile (so it would show up in the history)? The goal I'm working towards is making a Dockerfile reproducible without needing to modify the Dockerfile itself.
It would, for example, mean that build-cache does not apply between builds that use epoch and ones that do not, even if the run steps make no use of the added argument. I don't think avoiding changes in Dockerfile is a goal (in fact, we are probably adding #epoch), especially if the behavior of the Dockerfile commands changes. Ultimately it is the Dockerfile author who knows if the process they use in RUN
step understands the env variable or not.
LGTM but a couple of nits. Also needs rebase.
@AkihiroSuda ok to merge?
needs rebase, PTAL @AkihiroSuda
Looks like this needs a rebase again
OCI exporter needs to be fixed to reset "org.opencontainers.image.created" annotation
https://github.com/moby/buildkit/blob/092e977fd9ef49d865ed15b6e750b828bc2b1027/exporter/oci/export.go#L131
Is this going to apply as well for whiteout files?
And this timestamp is also non-reproducible
https://github.com/moby/buildkit/blob/092e977fd9ef49d865ed15b6e750b828bc2b1027/exporter/containerimage/export.go#L246-L249
Is this going to apply as well for whiteout files?
Needs:
- https://github.com/containerd/containerd/pull/7478