docker-maven-plugin icon indicating copy to clipboard operation
docker-maven-plugin copied to clipboard

Support reproducible docker image builds with Buildkit

Open modax opened this issue 1 year ago • 5 comments

Description

Latest Buildkit versions support reproducible builds (or rather make them easier to achieve). Currently, the plugin can only do reproducible builds from the docker build cache. More info:

  • https://reproducible-builds.org/docs/source-date-epoch/#dockerfile
  • https://github.com/moby/buildkit/blob/master/docs/build-repro.md

While it is possible to specify SOURCE_DATE_EPOCH with current plugin version (0.45.1) via various methods, I'm not aware of a method to specify rewrite-timestamp=true parameter for --output. Actually , BuildXService.java does not use --output at all at the moment.

Info

  • docker-maven-plugin version : 0.45.1
  • Maven version (mvn -v) : 3.8.8
  • Docker version : 27.4.0
  • If it's a feature request, what is your use case :

I would like to do reproducible docker builds regardless of docker build cache existence.

modax avatar Dec 12 '24 11:12 modax

I think SOURCE_DATE_EPOCH should be set to project.build.outputTimestamp - see #1844

jakub-bochenski avatar Dec 13 '24 17:12 jakub-bochenski

BTW @modax how can you "specify SOURCE_DATE_EPOCH with current plugin version"?

I mean other than setting an environment variable on the host - can it be done within maven?

jakub-bochenski avatar Dec 13 '24 17:12 jakub-bochenski

Hi,

I think SOURCE_DATE_EPOCH should be set to project.build.outputTimestamp - see #1844

  1. SOURCE_DATE_EPOCH takes seconds since epoch so project.build.outputTimestamp needs to be converted to it first. For me it is fine (I even prefer it to be different as long as it is stable) for SOURCE_DATE_EPOCH to be different from project.build.outputTimestamp. By the way, I set project.build.outputTimestamp to the maven 4 default. Some people set it to latest git commit date but I don't bother.
<project.build.outputTimestamp>1980-02-01T00:00:00Z</project.build.outputTimestamp>
  1. As stated in documentation, just SOURCE_DATE_EPOCH is not enough since it is does not rewrite all file timestamps in layers by default. This is what --rewrite-timestamps=true does. Technically, it is possible to craft such a Dockerfile which keeps timestamps stable but it might be tricky with things like COPY --link and similar (from my experience). You may have to dig image layers, grasp image creation internals to understand what might be wrong. --rewrite-timestamps=true would just be less painful in such a case.

BTW @modax how can you "specify SOURCE_DATE_EPOCH with current plugin version"?

I mean other than setting an environment variable on the host - can it be done within maven?

As far as documentation states, it can be both environment variable and build argument. I have not tested environment variable (which would be hackish imho) since I specify build argument ARG SOURCE_DATE_EPOCH="0" directly in my external Dockerfile. I have not tested it it would work as build arg from maven plugin configuration if there is no ARG SOURCE_DATE_EPOCH in the Dockerfile but looks like it should based on docs.

modax avatar Dec 14 '24 11:12 modax

For me it is fine (I even prefer it to be different as long as it is stable) for SOURCE_DATE_EPOCH to be different from project.build.outputTimestamp.

I mean project.build.outputTimestamp is the single point where you set all the output dates in Maven - for sake of consistency this should carry over to any Docker images built with Maven

jakub-bochenski avatar Dec 14 '24 16:12 jakub-bochenski

For me it is fine (I even prefer it to be different as long as it is stable) for SOURCE_DATE_EPOCH to be different from project.build.outputTimestamp.

I mean project.build.outputTimestamp is the single point where you set all the output dates in Maven - for sake of consistency this should carry over to any Docker images built with Maven

Sure thing, I don't mind.

modax avatar Dec 14 '24 18:12 modax