Customization point: Staging scripts
Overview​
This customization interacts with the customization of buildpacks.
Epinio uses staging scripts to interact with Paketo Cloud Native Buildpacks,
and to run Dockerfile builds for applications whose build mode
is dockerfile.
Epinio automatically selects the set of staging scripts based on the name of the chosen builder image, and the images supported by a specific definition.
By default Epinio installs three definitions.
- One to support Bionic-based builder images (
paketo-buildpacks/builder:*). - One to support Jammy-based builder images (
paketo-buildpacks/builder-jammy-*:*). - One to serve as fallback for any images not captured by the other two.
It is this last definition which is configured when customizing buildpacks with a different image.
By default this fallback is configured for Jammy-based images in general, and the jammy full stack paketo builder image in particular
Specification​
A set of staging scripts is represented by a kubernetes ConfigMap resource labeled
with app.kubernetes.io/component: epinio-staging.
This ConfigMap is expected to have the following keys:
| Key | Content |
|---|---|
builder | Glob-pattern to match the image references supported by this spec. |
userID | User ID to run the build script with. |
groupID | Group ID to run the build script with. |
env | Standard environment for the scripts, YAML-formatted string, key/value map. |
base | Optional redirect to the actual ConfigMap with the scripts. |
build | Shell script to compile the unpacked sources into an image. Executed using the chosen builder image |
downloadImage | Container image to run the download script with. |
download | Shell script to retrieve the app sources from the Epinio's S3 storage. Executed using the downloadImage |
unpackImage | Container image to run the unpack script with. |
unpack | Shell script to unpack the app sources into a directory tree. Executed using the unpackImage |
dockerfileBuildImage | Container image to run the dockerfile-build script with. |
dockerfile-build | Shell script to build the unpacked sources from a Dockerfile. Executed using the dockerfileBuildImage |
When base is specified it refers to a ConfigMap which contains all the keys listed after base.
If base and any of the keys listed after it are specified in the same resource then base has
priority.
This mechanism allows the sharing of script and image data between specifications differing only in
the user/group/environment required to run the build script.
User and group IDs, and general support for multiple staging scripts, was added because
the Bionic and Jammy-based builders use different numeric ids for their cnb user.
Env was added as the different builders may require different values for the CNB_PLATFORM_API
environment variable.
Staging script API, Download​
The download script is executed using the downloadImage and further configured
with four environment variables:
| Name | Content |
|---|---|
PROTOCOL | S3 storage, protocol |
ENDPOINT | S3 storage, primary endpoint |
BUCKET | S3 storage, name of bucket to read |
BLOBID | S3 storage, blod id/name of app sources, in the bucket |
Staging script API, Unpack​
The unpack script is executed using the unpackImage and further configured
with a single environment variable:
| Name | Content |
|---|---|
BLOBID | blob id / file name of the app source archive to unpack |
USERID | Numeric id of the cnb user used to run the build script |
GROUPID | Numeric id of the user group used to run the build script |
Staging script API, Build​
The build script is executed using the using the chosen builder image and further configured with
a two environment variables:
| Name | Content |
|---|---|
PREIMAGE | url to the result image from a previous push |
APPIMAGE | url to save the new application image under |
USERID | Numeric id of the cnb user used to run the build script |
GROUPID | Numeric id of the user group used to run the build script |
When present the PREIMAGE is used by /cnb/lifecycle/creator as a cache for layers,
speeding up compilation.
The build script is only used by applications whose build mode is buildpack. It is
the default mode, so it is used unless an application selects otherwise.
Staging script API, Dockerfile build​
For applications whose build mode is dockerfile, the dockerfile-build script
replaces build as the final staging step. It is executed using the
dockerfileBuildImage instead of the chosen builder image, and receives the same
environment as build plus one variable:
| Name | Content |
|---|---|
APPIMAGE | url to save the new application image under |
DOCKERFILE_PATH | Path of the Dockerfile to build, relative to the app sources |
DOCKERFILE_PATH is set only in this mode, and is validated by the API server before
the job is created. PREIMAGE, USERID, and GROUPID are present but unused by the
default script, which relies on its own layer cache instead of a previous image.
Unlike the build container, the dockerfile-build container runs without a
SecurityContext, so userID and groupID do not apply to it and its RUN steps
execute as root. See Build modes for what follows from
that.
Search​
Epinio determines the set of staging scripts to use by glob-matching the chosen builder image (name
and tag) against the builder key of all found specifications and selecting the first matching.
To ensure a deterministic search order the specifications are sorted lexicographically by name.
The exception to the above are specifications with builder == "*" or builder == "". These
specifications match everything and the last found is used as the fallback if and only if no other
specification matched.
If no specification matched, and no fallback was found, staging fails.
The search is driven by the builder image, which a Dockerfile build does not have, so
it does not apply to that mode. Dockerfile builds instead read the ConfigMap named
epinio-stage-scripts directly, and take their dockerfileBuildImage and
dockerfile-build script from it. That is the ConfigMap the chart installs as the
fallback specification, so in a default installation the two coincide, but a
Dockerfile build ignores any additional specification you add and fails if
epinio-stage-scripts carries no dockerfileBuildImage.