I'm creating a sample buildpack to get familiar with the internals of buildpack. Following the documentation on creating a new buildpack, I got it running but I have some points to get clarified regarding some concepts.
The documentation uses stacks to define the build and run images, but it is deprecated. I'm finding it hard to identify what the new alternative for it and couldn't find anything on how it can be done. I have also created base run and build images but am unsure how to use those without creating a stack.
For now (as of the time I write this), just use stacks. It'll work just fine while you're learning and it'll be simpler (cause there are more docs/examples available). It also will not be that difficult if you decide to keep working with buildpacks, you'll be able to migrate without a ton of effort.
As for the new tech, stacks are being removed and are being replaced with existing container terminology. This is a simplification because there's no buildpack-specific terminology to learn.
From the RFC that proposed the change:
This RFC proposes that we remove the stack ID concept from the project and replace it with existing constructs in the container image ecosystem such as operating system name, operating system version, and architecture.
https://github.com/buildpacks/rfcs/blob/main/text/0096-remove-stacks-mixins.md
A stack consists of a build image and a run image, so going forward they're just referred to that way. So you'll have a base image for build-time and a base image for run-time.
The other aspect of a stack is that it provides some metadata and compatibility assurances. These have been replaced with target metadata, like OS, version, variant, etc... You can see the full list in the RFC above. That's probably the best place to read about it for now, although I'm sure the docs will catch up and you can read about it there in the future.
Why does it (documentation) use a default builder when a stack is already defined for the build image. What use does the builder have in this context?
A stack is a build image and a run image. You can't invoke a stack directly though. When you pack build
an image, it doesn't work off a stack. It works off a builder.
A builder is basically a stack + buildpacks. More specifically, it's an image that uses the stack's build image and layers on top the suite of buildpacks that are included with the builder. In addition, it has metadata associated so that when you pack build
something, the tool knows the default run-image to use.
Thus when you pack build
something:
pack
takes the run image as the base image for the app image it's building and adds on top the layers created by the buildpacks. The result is run image + layers created by the buildpacks.Also, doesn't it affect the reproducibility of the buildpack because different builders can be used?
No, you can always reproduce an app image so long as you know the inputs. To get the same output (i.e. a reproducible build), you need the same input.
Inputs are:
If the inputs are all the same, then when you pack build
, the output image will be byte-for-byte the same.
The trick with builders is that you need to tell pack
the specific builder to use, either via tag or sha hash (the latter is better as it can't change). Otherwise, the builder image can float and you won't have the same input.