Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document reproducible builds #123

Merged
merged 5 commits into from
Apr 1, 2020
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions content/docs/reference/reproducibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
+++
title="Reproducible Builds"
weight=9
+++

## Summary
The Cloud Native Buildpacks project aims to create "Reproducible Builds" of container images. For image creation commands (`create-builder`, `package-buildpack`, `build`) `pack` creates container images in a reproducible fashion. "Reproducible" is hard to define but we'll do so by example and with a few caveats:

## Examples
---
Running `pack build sample-hello-moon:test` multiple times produces a container image with the same image ID (*local* case)

**Given**:
- The same source code
- The same builder image
- The same set of buildpacks (see caveat below).

---
Running `pack build cnbs/sample-hello-world:test --publish` multiple times produce a container image with the same image digest (*remote* case)

**Given**:
- The same source code
- The same builder image
- The same set of buildpacks (see caveat below).

Inspecting the results of the above command, we see the following output:

```bash
$ docker pull cnbs/sample-hello-world:test && docker images --digest # Pull remotely created image and view IDs and Digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
sample-hello-world test sha256:9e3cfea3f90fb4fbbe855a2cc9ce505087ae10d6805cfcb44bd67a4b72628641 597c49cae461 40 years ago 95.2MB
sample-hello-moon-app test <none> 86aab15e22b8 40 years ago 43MB
```

### Consequences and Caveats

There are a couple things to note about the above output:
- We achieve reproducible builds by "zeroing" various timestamps of the layers of the output image. When images are inspected they may have confusing creation times (eg. "40 years ago").
- The `cnbs/sample-hello-moon:test` image does not have an entry for the "DIGEST" column. This is because the digest is produced from the image's manifest and a manifest is only created when an image is stored in a remote registry.

The CNB lifecycle cannot fix non-reproducible buildpack layer file contents. This means that the underlying buildpack and language ecosystem have to implement reproducible output (for example `go` binaries are reproducible by default). Buildpacks that produce identical layers given the same input could be said to be reproducible buildpacks.

Running `pack build cnbs/test-image:test && docker push cnbs/test-image:test` and `pack build cnbs/test-image:test --publish` with the same inputs will not produce the same image digest because:
- The remote image will have an image digest reference in the `runImage.reference` field in the `io.buildpacks.lifecycle.metadata` label
- The local image will have an image ID in the `runImage.reference` field in the `io.buildpacks.lifecycle.metadata` label if it was created locally