Time Travel with Pack

Or, why your images were apparently created 40 years ago

David Freilich


One common question we get from Pack CLI users is

Why do images created by pack say they were created 40 years ago?

As the example below shows, the docker images command claims that an image I created using pack build, was created 40 years ago, which it most definitely was not.

What’s going on here?! That’s (a) a blatant lie, and (b) a very random time. But there’s a good explanation.

Reproducible Builds

This oddity comes down to a design decision that we made for the purpose of so-called “reproducible builds”; ensuring that you get the same result every time you run your build. Reproducible builds mean that whenever you run:

pack build sample-hello-moon:test

Pack will build a runnable image with the exact same image ID (also referred to as a sha / digest), assuming you have:

  • the same source code
  • the same builder image
  • the underlying buildpack/language support reproducible builds (for example, go binaries are reproducible by default)

Let’s demonstrate that, with an app and builder from our buildpacks/samples repo (specifically, the bash-script application, with the cnbs/sample-builder:bionic builder).

Two builds, with the same SHA

As you can see, two applications built at different times, with different names, have the same sha (in this case, 68ea4c6d5ddf). This happens even if you were to delete the docker cache. In contrast, if you would run a docker build after having deleted the cache, the resulting application would have a different sha.

Why is reproducibility important? Trust.

According to the Reproducible Builds Project,

The motivation … is therefore to allow verification that no vulnerabilities or backdoors have been introduced during this compilation process. By promising identical results are always generated from a given source, this allows multiple third parties to come to a consensus on a “correct” result, highlighting any deviations as suspect and worthy of scrutiny.

An image sha takes into account the contents of the image layers, including metadata, such as the date the image was produced. In order to get the desired reproducibility, we set some of the timestamps in the image (which would otherwise be different every second, and would thereby change the image ID) to January 1, 1980 00:00:01.

This date, January 1, 1980, wasn’t picked out of a hat — it was a deliberate choice, allowing us to extend support for files that use MS-DOS format (as some zip files for more details, see here). Interestingly, some other image building frameworks, like ko and jib do it as well.

There is a nice side-benefit for any students stressing about last minute coding assignments, though!

What do you mean, Professor? I finished the assignment a looooong time ago…