This document specifies the interface between a lifecycle and a platform.
A platform orchestrates a lifecycle to make buildpack functionality available to end-users such as application developers.
Examples of a platform might include:
- A local CLI tool that uses buildpacks to create OCI images
- A plugin for a continuous integration service that uses buildpacks to create OCI images
- A cloud application platform that uses buildpacks to build source code before deployment
- Platform Interface Specification
This document specifies Platform API version 0.3
.
Platform API versions:
- MUST be in form
<major>.<minor>
or<major>
, where<major>
is equivalent to<major>.0
- When
<major>
is greater than0
increments to<minor>
SHALL exclusively indicate additive changes
A buildpack refers to software compliant with the Buildpack Interface Specification.
A stack is a contract defined by a build image and a run image that are only updated with security patches.
A build image is an OCI image that provides the base of the build environment.
A run image is an OCI image that provides the base from which app images are built.
The build environment refers to the containerized environment in which the lifecycle executes buildpacks.
A mixin is a named set of additions to a stack that can be used to make additive changes to the contract.
An app image refers to an OCI image generated by the lifecycle by extending the run image with any or all of the following: app layers, launch layers, launcher layers, image configuration.
A launch layer refers to a layer in the app image created from a <layers>/<layer>
directory as specified in the Buildpack Interface Specification.
An app layer refers to a layer in the app image created from the <app>
directory as specified in the Buildpack Interface Specification.
A run image layer refers to a layer in the app image originating from the run image.
A launcher layer refers to a layer in the app OCI image containing the launcher itself and/or launcher configuration.
The launcher refers to a lifecycle executable packaged in the app image for the purpose of executing processes at runtime.
An image reference refers to either a tag reference or digest reference.
A tag reference refers to an identifier of form <registry>/<repo>:<tag>
which locates an image manifest in an OCI Distribution Specification compliant registry.
A digest reference refers to a content addressable identifier of form <registry>/<repo>@<digest>
which locates an image manifest in an OCI Distribution Specification compliant registry.
The following is a non-exhaustive list of terms defined in the OCI Image Format Specification used throughout this document:
- image config https://github.com/opencontainers/image-spec/blob/master/config.md#oci-image-configuration
- imageID - https://github.com/opencontainers/image-spec/blob/master/config.md#imageid
- diffID - https://github.com/opencontainers/image-spec/blob/master/config.md#layer-diffid
Stack image authors SHOULD ensure that build image versions maintain ABI-compatibility with previous versions, although violating this requirement will not change the behavior of previously built images containing app and launch layers.
Stack image authors MUST ensure that new run image versions maintain ABI-compatibility with previous versions. Stack image authors MUST ensure that app and launch layers do not change behavior when the run image layers are upgraded to newer versions, unless those behavior changes are intended to fix security vulnerabilities.
Mixin authors MUST ensure that mixins do not affect the ABI-compatibility of any object code compiled to run on the base stack images without mixins.
During build, platforms MUST use the same set of mixins for the run image as were used in the build image (excluding mixins that have a stage specifier).
The platform MUST ensure that:
- The image config's
User
field is set to a non-root user with a writable home directory. - The image config's
Env
field has the environment variableCNB_STACK_ID
set to the stack ID. - The image config's
Env
field has the environment variableCNB_USER_ID
set to the UID of the user specified in theUser
field. - The image config's
Env
field has the environment variableCNB_GROUP_ID
set to the primary GID of the user specified in theUser
field. - The image config's
Label
field has the labelio.buildpacks.stack.id
set to the stack ID. - The image config's
Label
field has the labelio.buildpacks.stack.mixins
set to a JSON array containing mixin names for each mixin applied to the image.
The platform MUST ensure that:
- The image config's
User
field is set to a user with the same UID and primary GID as in the build image. - The image config's
Label
field has the labelio.buildpacks.stack.id
set to the stack ID. - The image config's
Label
field has the labelio.buildpacks.stack.mixins
set to a JSON array containing mixin names for each mixin applied to the image.
A mixin name MUST only be defined by the author of its corresponding stack.
A mixin name MUST always be used to specify the same set of changes.
A mixin name MUST only contain a :
character as part of an optional stage specifier.
A mixin prefixed with the build:
stage specifier only affects the build image and does not need to be specified on the run image.
A mixin prefixed with the run:
stage specifier only affects the run image and does not need to be specified on the build image.
A platform MAY support any number of mixins for a given stack in order to support application code or buildpacks that require those mixins.
Changes introduced by mixins SHOULD be restricted to the addition of operating system software packages that are regularly patched with strictly backwards-compatible security fixes. However, mixins MAY consist of any changes that follow the Compatibility Guarantees.
The platform SHOULD set CNB_PLATFORM_API=<platform API version>
in the lifecycle's execution environment
If CNB_PLATFORM_API
is set in the lifecycle's execution environment, the lifecycle:
- MUST either conform to the matching version of this specification or
- MUST fail if it does not support
<platform API version>
A single app image build* consists of the following phases:
- Detection
- Analysis
- Cache Restoration
- Build*
- Export
A platform MUST execute these phases either by invoking the following phase-specific lifecycle binaries in order:
/cnb/lifecycle/detector
/cnb/lifecycle/analyzer
/cnb/lifecycle/restorer
/cnb/lifecycle/builder
/cnb/lifecycle/exporter
or by executing /cnb/lifecycle/creator
.
* build is an overloaded term that refers to both a single phase and the operation comprised of the above phases. The meaning of any particular instance of the word build must be assessed in context
When an updated run image with the same stack ID is available, an updated app image SHOULD be generated from the existing app image config by replacing the run image layers in the existing app image with the layers from the new run image. This is referred to as rebasing the app, launch, and launcher layers onto the new run image layers. When layers are rebased, any app image metadata referenceing to the original run image MUST be updated to reference to the new run image. This entire operation is referred to as rebasing the app image.
Rebasing allows for fast runtime OS-level dependency updates for app images without requiring a rebuild. A rebase requires minimal data transfer when the app and run images are colocated on a Docker registry that supports Cross Repository Blob Mounts.
To rebase an app image a platform MUST execute the /cnb/lifecycle/rebaser
or perform an equivalent operation.
/cnb/lifecycle/launcher
is responsible for launching user and buildpack provided processes in the correct execution environment.
/cnb/lifecycle/launcher
SHALL be the ENTRYPOINT
for all app images.
All lifecycle phases:
- MUST read
CNB_PLATFORM_API
from the execution environment and evaluate compatibility before attempting to parse other inputs (see Platform API Compatibility) - MUST give command line inputs precedence over other inputs
The platform MUST execute detector
in the build environment
Usage:
/cnb/lifecycle/detector \
[-app <app>] \
[-buildpacks <buildpacks>] \
[-group <group>] \
[-log-level <log-level>] \
[-order <order>] \
[-plan <plan>] \
[-platform <platform>]
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<app> |
CNB_APP_DIR |
/workspace |
Path to application directory |
<buildpacks> |
CNB_BUILDPACKS_DIR |
/cnb/buildpacks |
Path to buildpacks directory (see Buildpacks Directory Layout) |
<group> |
CNB_GROUP_PATH |
./group.toml |
Path to output group definition |
<log-level> |
CNB_LOG_LEVEL |
info |
Log Level |
<order> |
CNB_ORDER_PATH |
./order.toml |
Path to order definition (see order.toml (TOML)) |
<plan> |
CNB_PLAN_PATH |
./plan.toml |
Path to output resolved build plan |
<platform> |
CNB_PLATFORM_DIR |
/platform |
Path to platform directory |
Output | Description |
---|---|
[exit status] | Success (0), or error (1+) |
/dev/stdout |
Logs (info) |
/dev/stderr |
Logs (warnings, errors) |
<group> |
Detected buildpack group (see group.toml ) |
<plan> |
Resolved Build Plan (see plan.toml ) |
The lifecycle:
- SHALL detect a single group from
<order>
and write it to<group>
using the detection process outlined in the Buildpack Interface Specification - SHALL write the resolved build plan from the detected group to
<plan>
Usage:
/cnb/lifecycle/analyzer \
[-analyzed <analyzed>] \
[-cache-dir <cache-dir>] \
[-cache-image <cache-image>] \
[-daemon] \ # sets <daemon>
[-gid <gid>] \
[-group <group>] \
[-layers <layers>] \
[-log-level <log-level>] \
[-skip-layers <skip-layers>] \
[-uid <uid>] \
<image>
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<analyzed> |
CNB_ANALYZED_PATH |
./analyzed.toml |
Path to output analysis metadata (see analyzed.toml (TOML) |
<cache-dir> |
CNB_CACHE_DIR |
Location of cache, provided as a directory | |
<cache-image> |
CNB_CACHE_IMAGE |
Location of cache, provided as an image | |
<daemon> |
CNB_USE_DAEMON |
false |
Analyze image from docker daemon |
<gid> |
CNB_GROUP_ID |
Primary GID of the stack User |
|
<group> |
CNB_GROUP_PATH |
./group.toml |
Path to group definition (see group.toml (TOML)) |
<image> |
Image reference to be analyzed (usually the result of the previous build) | ||
<layers> |
CNB_LAYERS_DIR |
/layers |
Path to layers directory |
<log-level> |
CNB_LOG_LEVEL |
info |
Log Level |
<skip-layers> |
CNB_SKIP_LAYERS |
false |
Do not perform layer analysis |
<uid> |
CNB_USER_ID |
UID of the stack User |
- If
<daemon>
isfalse
,<image>
MUST be a valid image reference - If
<daemon>
istrue
,<image>
MUST be either a valid image reference or an imageID - The lifecycle MUST accept valid references to non-existent images without error.
Output | Description |
---|---|
[exit status] | Success (0), or error (1+) |
/dev/stdout |
Logs (info) |
/dev/stderr |
Logs (warnings, errors) |
<analyzed> |
Analysis metadata (see analyzed.toml |
<layers>/<buidpack-id>/<layer>.sha |
Files containing the diffID of each analyzed layer |
<layers>/<buidpack-id>/<layer>.toml |
Files containing the layer content metadata of each analyzed layer (see data format in Buildpack Interface Specification) |
- The lifecycle MUST write analysis metadata to
<analyzed>
if<image>
is accessible. - If
<skip-layers>
isfalse
the lifecycle MUST analyze any app image layers or cached layers created by any buildpack present in the provided<group>
. - If
<skip-layers>
istrue
the lifecycle MUST NOT perform layer analysis.
When analyzing a given layer the lifecycle SHALL:
- If
build=true
,cache=false
:- Do nothing
- Else if
launch=true
:- Write layer metadata read from the analyzed image to
<layers>/<buildpack-id>/<layer-name>.toml
- Write the layer diffID from the analyzed image to
<layers>/<buildpack-id>/<layer-name>.sha
- Write layer metadata read from the analyzed image to
- Else if
cache=true
:- Write layer metadata read from the cache to
<layers>/<buildpack-id>/<layer-name>.toml
- Write the layer diffID from the cache to
<layers>/<buildpack-id>/<layer-name>.sha
- Write layer metadata read from the cache to
Usage:
/cnb/lifecycle/restorer \
[-cache-dir <cache-dir>]
[-cache-image <cache-image>]
[-gid <gid>] \
[-group <group>] \
[-layers <layers>] \
[-log-level <log-level>] \
[-uid <uid>]
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<cache-dir> |
CNB_CACHE_DIR |
Path to a cache directory | |
<cache-image> |
CNB_CACHE_IMAGE |
Reference to a cache image in an OCI image registry | |
<gid> |
CNB_GROUP_ID |
Primary GID of the stack User |
|
<group> |
CNB_GROUP_PATH |
./group.toml |
Path to group definition (see group.toml ) |
<layers> |
CNB_LAYERS_DIR |
/layers |
Path to layers directory |
<log-level> |
CNB_LOG_LEVEL |
info |
Log Level |
<uid> |
CNB_USER_ID |
UID of the stack User |
|
<layers>/<buidpack-id>/<layer>.sha |
Files containing the diffID of each analyzed layer | ||
<layers>/<buidpack-id>/<layer>.toml |
Files containing the layer content metadata of each analyzed layer (see data format in Buildpack Interface Specification) |
Output | Description |
---|---|
[exit status] | Success (0), or error (1+) |
/dev/stdout |
Logs (info) |
/dev/stderr |
Logs (warnings, errors) |
<layers>/<buidpack-id>/<layer>/* |
Restored layer contents |
For each layer metadata file found in the <layers>
directory, the lifecycle:
- MUST restore cached layer contents if the cache contains a layer with matching diffID
- MUST remove layer metadata if
cache=true
AND the cache DOES NOT contain a layer with matching diffID
The platform MUST execute builder
in the build environment
Usage:
/cnb/lifecycle/builder \
[-app <app>] \
[-buildpacks <buildpacks>] \
[-group <group>] \
[-layers <layers>] \
[-log-level <log-level>] \
[-plan <plan>] \
[-platform <platform>]
Input | Env | Default Value | Description |
---|---|---|---|
<app> |
CNB_APP_DIR |
/workspace |
Path to application directory |
<buildpacks> |
CNB_BUILDPACKS_DIR |
/cnb/buildpacks |
Path to buildpacks directory (see Buildpacks Directory Layout) |
<group> |
CNB_GROUP_PATH |
./group.toml |
Path to group definition (see group.toml ) |
<layers> |
CNB_LAYERS_DIR |
/layers |
Path to layers directory |
<log-level> |
CNB_LOG_LEVEL |
info |
Log Level |
<plan> |
CNB_PLAN_PATH |
./plan.toml |
Path to resolved build plan (see plan.toml ) |
<platform> |
CNB_PLATFORM_DIR |
/platform |
Path to platform directory |
Output | Description |
---|---|
[exit status] | Success (0), or error (1+) |
/dev/stdout |
Logs (info) |
/dev/stderr |
Logs (warnings, errors) |
<layers>/<buildpack ID>/<layer> |
Layer contents (see Buildpack Interface Specfication |
<layers>/<buildpack ID>/<layer>.toml |
Layer metadata (see Buildpack Interface Specfication |
<layers>/config/metadata.toml |
Build metadata (see metadata.toml ) |
- The lifecycle SHALL execute all buildpacks in the order defined in
<group>
according process outlined in the Buildpack Interface Specification. - The lifecycle SHALL add all invoked buildpacks to
<layers>/config/metadata.toml
. - The lifecycle SHALL aggregate all
processes
,slices
and BOM entries returned by buildpacks in<layers>/config/metadata.toml
.
Usage:
/cnb/lifecycle/exporter \
[-analyzed <analyzed>] \
[-app <app>] \
[-cache-dir <cache-dir>] \
[-cache-image <cache-image>] \
[-daemon] \ # sets <daemon>
[-gid <gid>] \
[-group <group>] \
[-launch-cache <launch-cache> ] \
[-launcher <launcher> ] \
[-layers <layers>] \
[-log-level <log-level>] \
[-process-type <process-type> ] \
[-project-metadata <project-metadata> ] \
[-run-image <run-image> | -image <run-image> ] \ # -image is Deprecated
[-stack <stack>] \
[-uid <uid> ] \
<image> [<image>...]
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<analyzed> |
CNB_ANALYZED_PATH |
./analyzed.toml |
Path to analysis metadata (see analyzed.toml (TOML) |
<app> |
CNB_APP_DIR |
/workspace |
Path to application directory |
<cache-dir> |
CNB_CACHE_DIR |
Path to a cache directory | |
<cache-image> |
CNB_CACHE_IMAGE |
Reference to a cache image in an OCI image registry | |
<daemon> |
CNB_USE_DAEMON |
false |
Export image to docker daemon |
<gid> |
CNB_GROUP_ID |
Primary GID of the stack User |
|
<group> |
CNB_GROUP_PATH |
./group.toml |
Path to group file (see group.toml ) |
<image> |
Tag reference to which the app image will be written | ||
<launch-cache> |
CNB_LAUNCH_CACHE_DIR |
Path to a cache directory containing launch layers | |
<launcher> |
/cnb/lifecycle/launcher |
Path to the launcher executable |
|
<layers> |
CNB_LAYERS_DIR |
/layers |
Path to layer directory |
<log-level> |
CNB_LOG_LEVEL ` |
info |
Log Level |
<process-type> |
CNB_PROCESS_TYPE |
Default process type to set in the exported image | |
<project-metadata> |
CNB_PROCESS_TYPE |
./project-metadata.toml |
Path to a project metadata file (see project-metadata.toml (TOML) |
<run-image> |
CNB_RUN_IMAGE |
resolved from <stack> |
Run image reference |
<stack> |
CNB_STACK_PATH |
/cnb/stack.toml |
Path to stack file (see stack.toml (TOML) |
<uid> |
CNB_USER_ID |
UID of the stack User |
|
<layers>/config/metadata.toml |
Build metadata (see metadata.toml (TOML) |
- At least one
<image>
must be provided - Each
<image>
MUST be a valid tag reference - If
<daemon>
isfalse
and more than one<image>
is provided they MUST refer to the same registry - If
<run-image>
is not provided by the platform the value will be resolved from the contents ofstack
Output | Description |
---|---|
[exit status] |
Success (0), or error (1+) |
/dev/stdout |
Logs (info) |
/dev/stderr |
Logs (warnings, errors) |
<image> |
Exported app image (see Buildpack Interface Specfication |
- The lifecycle SHALL write the same app image to each
<image>
tag - The app image:
- MUST be an extension of the
<run-image>
- All run-image layers SHALL be preserved
- All run-image config values SHALL be preserved unless this conflict with another requirement
- MUST contain all buildpack-provided launch layers as determined by the Buildpack Interface Specfication
- MUST contain one or more app layers as determined by the Buildpack Interface Specfication
- MUST contain a layer that includes
<launcher>
- MUST contain a layer that includes
<layers>/config/metadata.toml
- MUST have
ENTRYPOINT=<launcher>
- MUST contain the following
Env
entries"CNB_LAYERS_DIR=<layers>"
"CNB_APP_DIR=<app>"
- MUST contain the following
Env
entry, if<process-type>
is set"CNB_PROCESS_TYPE=<process-type>"
- MUST contain the following labels
io.buildpacks.lifecycle.metadata
: see lifecycle metadata label (JSON)io.buildpacks.project.metadata
: the value of which SHALL be the json representation<project-metadata>
io.buildpacks.build.metadata
: see build metadata (JSON)
- MUST be an extension of the
- To ensure build reproducibility, the lifecycle:
- SHOULD set the modification time of all files in newly created layers to a constant value
- SHOULD set the
created
time in image config to a constant value
If a cache is provided the lifecycle:
- SHALL write the contents of all cached layers to the cache
- SHALL record the diffID and layer content metadata of all cached layers in the cache
The platform MUST execute creator
in the build environment
Usage:
/cnb/lifecycle/creator \
[-app <app>] \
[-cache-dir <cache-dir>] \
[-cache-image <cache-image>] \
[-daemon] \ # sets <daemon>
[-gid <gid>] \
[-launch-cache <launch-cache> ] \
[-launcher <launcher> ] \
[-layers <layers>] \
[-log-level <log-level>] \
[-order <order>] \
[-platform <platform>] \
[-previous-image <previous-image> ] \
[-process-type <process-type> ] \
[-project-metadata <project-metadata> ] \
[-run-image <run-image>] \
[-skip-restore <skip-restore>] \
[-stack <stack>] \
[-tag <tag>...] \
[-uid <uid> ] \
<image>
Running creator
SHALL be equivalent to running detector
, analzyer
, restorer
, builder
and exporter
in order with identical inputs where they are accepted, with the following exceptions.
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<previous-image> |
CNB_PREVIOUS_IMAGE |
<image> |
Image reference to be analyzed (usually the result of the previous build) |
<skip-restore> |
CNB_SKIP_RESTORE |
false |
Do not write layer metadata or restore cached layers |
<tag>... |
Additional tag to apply to exported image |
- If
<skip-restore>
istrue
thecreator
SHALL skip layer analysis and skip the entire Restore phase. - If the platform provides one or more
<tag>
inputs they SHALL be treated as additional<image>
inputs to theexporter
Outputs produced by creator
are identical to those produced by exporter
.
Usage:
/cnb/lifecycle/rebaser \
[-daemon] \ # sets <daemon>
[-gid <gid>] \
[-log-level <log-level>] \
[-run-image <run-image> | -image <run-image> ] \ # -image is Deprecated
[-uid <uid>] \
<image> [<image>...]
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<daemon> |
CNB_USE_DAEMON |
false |
Export image to docker daemon |
<gid> |
CNB_GROUP_ID |
Primary GID of the stack User |
|
<image> |
App image to rebase | ||
<log-level> |
CNB_LOG_LEVEL |
info |
Log Level |
<run-image> |
CNB_RUN_IMAGE |
derived from <image> |
Run image reference |
<uid> |
CNB_USER_ID |
UID of the stack User |
- At least one
<image>
must be provided - Each
<image>
MUST be a valid tag reference - If
<daemon>
isfalse
and more than one<image>
is provided they MUST refer to the same registry - If
<run-image>
is not provided by the platform the value will be resolved from the contents of thestack
key in theio.buildpacks.lifecycle.metdata
label on<image>
.
Output | Description |
---|---|
[exit status] | Pass (0), or error (1+) |
/dev/stdout |
Logs (info) |
/dev/stderr |
Logs (warnings, errors) |
<image> |
Rebased app image (see Buildpack Interface Specfication |
- The lifecycle SHALL write the same app image to each
<image>
tag - The rebased app image SHALL be identical to
<image>
, with the following modifications:- Run image layers SHALL be defined as Layers in
<image>
up to and including the layer with diff ID matching the value ofrun-image.top-layer
from theio.buildpacks.lifecycle.metadata
label - Run image layers SHALL be replaced with the layers from the new
<run-image>
- The value of
io.buildpacks.lifecycle.metadata
SHALL be modified as followsrun-image.reference
SHALL uniquely identify<run-image>
run-image.top-layer
SHALL be set to the uncompressed digest of the top layer in<run-image>
- Run image layers SHALL be defined as Layers in
- To ensure build reproducibility, the lifecycle:
- Set the
created
time in image config to a constant
- Set the
Usage:
/cnb/lifecycle/launcher [--] [<cmd> <arg>...]
Input | Environment Variable | Default Value | Description |
---|---|---|---|
<app> |
CNB_APP_DIR |
/workspace |
Path to application directory |
<layers> |
CNB_LAYERS_DIR |
/layers |
Path to layer directory |
<process-type> |
CNB_PROCESS_TYPE |
web |
type of process to launch |
<direct> |
Process execution strategy | ||
<cmd> |
Command to execute | ||
<args> |
Arguments to command | ||
<layers>/config/metadata.toml |
Build metadata (see metadata.toml |
||
<layers>/<buildpack-id>/<layer>/ |
Launch Layers |
A command (<cmd>
), arguments to that command (<args>
), and an execution strategy (<direct>
) comprise a process definition. Processes MAY be buildpack-defined or user-defined.
The launcher:
- MUST select a single process
- MUST construct the process execution environment as described in Launch Environment
- MUST execute the process as specified in the Buildpack Interface Specfication
- SHOULD replace the lifecycle with the process in memory without forking it.
- If zero positional arguments are provided to the launcher, the lifecycle
- MUST select the process with
type
equal to<process-type>
from<layers>/config/metadata.toml
- MUST select the process with
- Else
- If
$1
is--
<direct>
SHALL betrue
<cmd>
SHALL be$2
<args>
SHALL be${@3:}
- Else
<direct>
SHALL befalse
<cmd>
SHALL be$1
<args>
SHALL be${@2:}
- If
Given stack metadata containing run-image.image
and a set of run-image.mirrors
. The <run-image>
for a given <image>
shall be resolved as follows:
- If any of
run-image.image
orrun-image.mirrors
has a registry matching that of<image>
, this value will become the<run-image>
- If none of
run-image.image
orrun-image.mirrors
has a registry matching that of<image>
,<run-image.image>
will become the<run-image>
The platform MAY set CNB_REGISTRY_AUTH
in the lifecycle execution environment, where value of CNB_REGISTRY_AUTH
MUST be valid JSON object and MAY contain any number of <regsitry>
to <auth-header>
mappings.
If CNB_REGISTRY_AUTH
is set and <registry>
matches the registry of an image reference, the lifecycle SHOULD set the value of the Authorization
HTTP header to <auth-header>
when attempting to read or write the image located at the given reference.
If CNB_REGISTRY_AUTH
is unset and a docker config.json file is present, the lifecycle SHOULD use the contents of this file to authenticate with any matching registry.
The lifecycle SHOULD adhere to established docker conventions when checking for the existence of or interpreting the contents of a config.json
file.
The lifecycle MAY provide other mechanisms by which a platform can supply registry credentials.
The lifecycle MUST attempt to authenticate anonymously if no matching credentials are found.
The buildpacks directory MUST contain unarchived buildpacks such that:
- Each top-level directory is a buildpack ID.
- Each second-level directory is a buildpack version.
The platform SHOULD run each phase of the lifecycle in an isolated container to prevent untrusted app and buildpack code from accessing storage credentials needed during the export and analysis phases. A more thorough explanation is provided in the Buildpack Interface Specification.
The following variables SHOULD be set in the lifecycle execution environment and SHALL be directly inherited by the buildpack without modification:
Env Variable | Description |
---|---|
CNB_STACK_ID |
Chosen stack ID |
HOME |
Current user's home directory |
The following variables SHOULD be set in the lifecycle execution environment and MAY be modified by prior buildpacks before they are provided to a given buildpack:
Env Variable | Layer Path | Contents |
---|---|---|
PATH |
/bin |
binaries |
LD_LIBRARY_PATH |
/lib |
shared libraries |
LIBRARY_PATH |
/lib |
static libraries |
CPATH |
/include |
header files |
PKG_CONFIG_PATH |
/pkgconfig |
pc files |
The platform SHOULD NOT assume any other stack-provided environment variables are inherited by the buildpack.
User-provided environment variables MUST be supplied by the platform as files in the <platform>/env/
directory.
Each file SHALL define a single environment variable, where the file name defines the key and the file contents define the value.
User-provided environment variables MAY be modified by prior buildpacks before they are provided to a given buildpack.
The platform SHOULD NOT set user-provided environment variables directly in the lifecycle execution environment.
User-provided modifications to the process execution environment SHOULD be set directly in the lifecycle execution environment.
The process SHALL inherit both stack-provided and user-provided variables from the lifecycle execution environment with the following exceptions:
CNB_APP_DIR
,CNB_LAYERS_DIR
andCNB_PROCESS_TYPE
SHALL NOT be set in the process execution environment.- The lifecycle SHALL apply buildpack-provided modifications to the environment as outlined in the Buildpack Interface Specification.
If caching is enabled the platform is responsible for providing the lifecycle with access to the correct cache. Whenever possible, the platform SHOULD provide the same cache to each rebuild of a given app image. Cache locality and availability MAY vary between platforms.
When given identical inputs all build and rebase operations:
- SHOULD produce app images with identical imageIDs
- If exporting directly to a registry
- SHOULD produce app images with identical manifest digests
- MAY output other non-reproducible artifacts
To achieve reproducibility the lifecycle SHOULD set the following to a constant, rather than an accurate value:
- file modification times in generated layers
- image creation time
Because compressions algorithms and manifest whitespace affect the image digest, an app image exported to the docker daemon and subsequently pushed to a registry MAY have a different digest than an app image exported directly to a registry by the lifecycle, even when all other inputs are held constant.
If buildpacks do not generate layer contents or layer metadata reproducibly, builds MAY NOT be reproducibile even when identical source code and buildpacks are provided to the lifecycle.
All app image labels SHOULD contain only reproducible values.
For more information on build reproducibility see https://reproducible-builds.org/
[image]
reference = "<image reference>"
[metadata]
# layer metadata
Where:
image.reference
MUST be either a digest reference to an image in a docker registry or the ID of an image in a docker daemonmetadata
MUST be the TOML representation of the layer metadata label
group = [
{ id = "<buildpack ID>", version = "<buildpack version>" }
]
Where:
- Both
id
andversion
MUST be present for each buildpack object in a group.
[[buildpacks]]
id = "<buildpack ID>"
version = "<buildpack Version>"
optional = false
[[processes]]
type = "<process type>"
command = "<command>"
args = ["<arguments>"]
direct = false
[[slices]]
paths = ["<app sub-path glob>"]
[bom]
Where:
- Both
id
andversion
MUST be present for each buildpack. processes
contains the complete set of processes contributed by all buildpacksprocesses
contains the complete set of slice defined by all buildpacksbom
contains the Bill of Materials
[[order]]
[[order.group]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = false
Where:
- Both
id
andversion
MUST be present for each buildpack object in a group. - The value of
optional
MUST default to false if not specified.
[[entries]]
[[entries.providers]]
id = "<buildpack ID>"
version = "buildpack Version"
[[entries.requires]]
name = "<dependency name>"
[entries.requires.metadata]
# arbitrary data describing the required dependency
Where:
entries
MAY be empty- Each entry:
- MUST contain at least one buildpack in
providers
- MUST contain at least one dependency requirement in
requires
- MUST exclusively contain dependency requirements with the same
<dependency name>
- MUST contain at least one buildpack in
[source]
type = "<source type>"
[source.version]
# arbitrary data
[source.metadata]
# arbitrary data
Where:
- All values are optional
type
, if present, SHOULD contain the type of location where the provided app source is stored (e.ggit
,s3
)version
, if present, SHOULD contain data uniquely identifying the particular version of the provided sourcemetadata
MAY contain additional arbitrary data about the provided source
[run-image]
image = "<image>"
mirrors = ["<mirror>", "<mirror>"]
Where:
run-image.image
MAY be a reference to a run image in a docker registryrun-image.mirrors
MUST NOT be present ifrun-image.image
is not presentrun-image.mirrors
MAY contain one or more tag references to run images in docker registries- All
run-image.mirrors
:- SHOULD reference an image with ID identical to that of
run-image.image
- SHOULD reference an image with ID identical to that of
run-image.image
andrun-image.mirrors.[]
SHOULD each refer to a unique registry
{
"processes": [
{
"type": "<process-type>",
"command": "<command>",
"args": [
"<args>"
],
"direct": false
}
],
"buildpacks": [
{
"id": "<buildpack ID>",
"version": "<buildpack Version>"
}
],
"bom": [
{
"name": "<bom-entry-name>",
"version": "<bom-entry-version>",
"metadata": {
// arbitrary buildpack provided metadata
},
"buildpack": {
"id": "<buildpack ID>",
"version": "<buildpack Version>"
}
},
],
"launcher": {
"version": "<launcher-version>",
"source": {
"git": {
"repository": "<launcher-source-repository>",
"commit": "<launcher-source-commit>"
}
}
}
}
Where:
processes
MUST contain all buildpack contributed processesbuildpacks
MUST contain the detected groupbom
MUST contain the Bill of Materialslauncher.version
SHOULD contain the version of thelauncher
binary included in the appluancher.source.git.repository
SHOULD contain the git repository containing thelauncher
source codeluancher.source.git.commit
SHOULD contain the git commit from which the givenlauncher
was built
{
"app": [
{"sha": "<slice-layer-diffID>"}
],
"config": {
"sha": "<config-layer-diffID>"
},
"launcher": {
"sha": "<launcher-layer-diffID>"
},
"buildpacks": [
{
"key": "<buldpack-id>",
"version": "<buildpack-version>",
"layers": {
"<layer-name>": {
"sha": "<layer-diffID>",
"data": {},
"build": false,
"launch": false,
"cache": false
}
}
}
],
"runImage": {
"topLayer": "<run-image-top-layer-diffID>",
"reference": "<run-image-reference>"
},
"stack": {
"runImage": {
"image": "cnbs/sample-stack-run:bionic"
}
}
}
Where:
app
MUST contain one entry per app slice layer wheresha
MUST contain the digest of the uncompressed layer
config.sha
MUST the digest of the uncompressed layer containing launcher configlauncher.sha
MUST the digest of the uncompressed layer containing the launcher binarybuildpacks
MUST contain one entry per buildpack that participated in the build wherekey
is required and MUST contain the buildpack IDversion
is required and MUST contain the buidpack Versionlayers
is required and MUST contain one entry per launch layer contributed by the given buildpack.- For each entry in
layers
:- The key MUST be the name of the layer
- The value MUST contain JSON representation of the
layer.toml
with an additionalsha
key, containing the digest of the uncompressed layer - The value MUST contain an additional
sha
key, containing the digest of the uncompressed layer
run-image.topLayer
must contain the uncompressed digest of the top layer of the run-imagerun-image.reference
MUST uniquely identify the run image. It MAY contain one of the following- An image ID (the digest of the uncompressed config blob)
- A digest reference to a manifest stored in an OCI image registry
stack
MUST contain the json representation ofstack.toml
{
"source": {
"type": "<type",
"version": {
// arbitrary version data
},
"metadata": {
// arbitrary data
}
}
}
This label MUST contain the JSON representation of project-metadata.toml