buildkit icon indicating copy to clipboard operation
buildkit copied to clipboard

Add support for SOURCE_DATE_EPOCH

Open tonistiigi opened this issue 2 years ago • 8 comments

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

tonistiigi avatar Jun 21 '22 04:06 tonistiigi

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

crazy-max avatar Jun 23 '22 09:06 crazy-max

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?

sudo-bmitch avatar Jul 03 '22 23:07 sudo-bmitch

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.

tonistiigi avatar Jul 14 '22 22:07 tonistiigi

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.

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.

sudo-bmitch avatar Jul 14 '22 22:07 sudo-bmitch

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.

tonistiigi avatar Jul 18 '22 23:07 tonistiigi

LGTM but a couple of nits. Also needs rebase.

AkihiroSuda avatar Jul 23 '22 03:07 AkihiroSuda

@AkihiroSuda ok to merge?

tonistiigi avatar Aug 08 '22 23:08 tonistiigi

needs rebase, PTAL @AkihiroSuda

crazy-max avatar Sep 02 '22 11:09 crazy-max

Looks like this needs a rebase again

thaJeztah avatar Sep 28 '22 07:09 thaJeztah

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

AkihiroSuda avatar Oct 04 '22 11:10 AkihiroSuda

Is this going to apply as well for whiteout files?

spacedub avatar Oct 05 '22 01:10 spacedub

And this timestamp is also non-reproducible

https://github.com/moby/buildkit/blob/092e977fd9ef49d865ed15b6e750b828bc2b1027/exporter/containerimage/export.go#L246-L249

AkihiroSuda avatar Oct 05 '22 05:10 AkihiroSuda

Is this going to apply as well for whiteout files?

Needs:

  • https://github.com/containerd/containerd/pull/7478

AkihiroSuda avatar Oct 07 '22 23:10 AkihiroSuda