diff --git a/content/docs/.common/concepts/extension.md b/content/docs/.common/concepts/extension.md index e7a13ddc4..fef21839f 100644 --- a/content/docs/.common/concepts/extension.md +++ b/content/docs/.common/concepts/extension.md @@ -34,7 +34,7 @@ provide. By contrast, Dockerfiles are the most-used and best-understood mechanis installing OS-level dependencies for containers. The CNB Dockerfiles feature allows Dockerfiles to "provide" dependencies that buildpacks "require" through a -shared [build plan](/docs/reference/spec/buildpack-api/#build-plan), by introducing the concept of image extensions. +shared [build plan], by introducing the concept of image extensions. ## What do they look like? @@ -67,7 +67,7 @@ The extension determines if it is needed or not. Like buildpacks, extensions participate in the `detect` phase - analyzing application source code to determine if they are needed. During `detect`, extensions can contribute to -the [build plan](/docs/reference/spec/buildpack-api/#build-plan) - recording dependencies that they are able to " +the [build plan] - recording dependencies that they are able to " provide" (though unlike buildpacks, they can't "require" anything). If the provided order contains extensions, the output of `detect` will be a group of image extensions and a group of @@ -80,3 +80,5 @@ The extension outputs Dockerfiles that can be used to extend either or both of t For more information and to see a build in action, see [authoring an image extension](/docs/for-buildpack-authors/tutorials/basic-extension). + +[build plan]: /docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan \ No newline at end of file diff --git a/content/docs/for-buildpack-authors/concepts/caching-strategies.md b/content/docs/for-buildpack-authors/concepts/caching-strategies.md index fd411c5d6..18ef19940 100644 --- a/content/docs/for-buildpack-authors/concepts/caching-strategies.md +++ b/content/docs/for-buildpack-authors/concepts/caching-strategies.md @@ -14,7 +14,7 @@ There are three types of layers that can be contributed to an image * `build` layers -- the directory will be accessible by subsequent buildpacks, * `cache` layers -- the directory will be included in the cache, -* `launch` layers -- the directory will be included in the run image as a single layer, +* `launch` layers -- the directory will be included in the final app image as a single layer, In this section we look at caching each layer type. diff --git a/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/craft-order.md b/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/craft-order.md new file mode 100644 index 000000000..8dc0268cb --- /dev/null +++ b/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/craft-order.md @@ -0,0 +1,10 @@ ++++ +title="Craft a buildpack order" +weight=99 ++++ + + + +This page is a stub! The CNB project is applying to [Google Season of Docs](https://developers.google.com/season-of-docs/docs/timeline) to receive support for improving our documentation. Please check back soon. + +If you are familiar with this content and would like to make a contribution, please feel free to open a PR :) diff --git a/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/package-buildpack.md b/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/package-buildpack.md index 57c13c0c1..980fd0daa 100644 --- a/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/package-buildpack.md +++ b/content/docs/for-buildpack-authors/how-to/distribute-buildpacks/package-buildpack.md @@ -4,7 +4,7 @@ title="Package a buildpack or extension" aliases=[ "/docs/buildpack-author-guide/package-a-buildpack" ] -weight=5 +weight=4 summary="Learn how to package your buildpack or extension for distribution." +++ diff --git a/content/docs/for-buildpack-authors/how-to/write-buildpacks/add-sbom.md b/content/docs/for-buildpack-authors/how-to/write-buildpacks/add-sbom.md index 58d34627e..d177bc2ae 100644 --- a/content/docs/for-buildpack-authors/how-to/write-buildpacks/add-sbom.md +++ b/content/docs/for-buildpack-authors/how-to/write-buildpacks/add-sbom.md @@ -1,6 +1,6 @@ +++ title="Provide a Software Bill-of-Materials" -weight=2 +weight=5 +++ Buildpacks can provide a [Software `Bill-of-Materials`](https://en.wikipedia.org/wiki/Software_bill_of_materials) (SBOM) diff --git a/content/docs/for-buildpack-authors/how-to/write-buildpacks/create-layer.md b/content/docs/for-buildpack-authors/how-to/write-buildpacks/create-layer.md index a56b377c1..a1804737b 100644 --- a/content/docs/for-buildpack-authors/how-to/write-buildpacks/create-layer.md +++ b/content/docs/for-buildpack-authors/how-to/write-buildpacks/create-layer.md @@ -1,10 +1,50 @@ +++ title="Create dependency layers" -weight=99 +weight=3 +++ +Each directory created by the buildpack under the `CNB_LAYERS_DIR` can be used as a layer in the final app image or build cache. + -This page is a stub! The CNB project is applying to [Google Season of Docs](https://developers.google.com/season-of-docs/docs/timeline) to receive support for improving our documentation. Please check back soon. +That is, each directory can be used for any of the following purposes: + +| Layer Type | | +|------------|-------------------------------------------------------------------------------------------------------------| +| `Launch` | the directory will be included in the **final app image** as a single layer | +| `Cache` | the directory will be included in the **build cache** and restored to the `CNB_LAYERS_DIR` on future builds | +| `Build` | the directory will be accessible to **buildpacks that follow** in the build (via the environment) | + +A buildpack can control how a layer will be used by creating a `.toml` with a name matching the directory it describes in the `CNB_LAYERS_DIR`. + +### Example + +A buildpack might create a `$CNB_LAYERS_DIR/python` directory and a `$CNB_LAYERS_DIR/python.toml` with the following contents: + +``` +launch = true +cache = true +build = true +``` + +In this example: +* the final app image will contain a layer with `python`, as this is needed to run the app +* the `$CNB_LAYERS_DIR/python` directory will be pre-created for future builds, avoiding the need to re-download this large dependency +* buildpacks that follow in the build will be able to use `python` + +### Example + +This is a simple `./bin/build` script for a buildpack that runs Python's `pip` package manager to resolve dependencies: + +``` +#!/bin/sh + +PIP_LAYER="$CNB_LAYERS_DIR/pip" +mkdir -p "$PIP_LAYER/modules" "$PIP_LAYER/env" + +pip install -r requirements.txt -t "$PIP_LAYER/modules" \ + --install-option="--install-scripts=$PIP_LAYER/bin" \ + --exists-action=w --disable-pip-version-check --no-cache-dir -If you are familiar with this content and would like to make a contribution, please feel free to open a PR :) +echo "launch = true" > "$PIP_LAYER.toml" +``` diff --git a/content/docs/for-buildpack-authors/how-to/write-buildpacks/get-started.md b/content/docs/for-buildpack-authors/how-to/write-buildpacks/get-started.md new file mode 100644 index 000000000..542236c29 --- /dev/null +++ b/content/docs/for-buildpack-authors/how-to/write-buildpacks/get-started.md @@ -0,0 +1,111 @@ ++++ +title="Get started" +weight=1 ++++ + +To write a buildpack, we follow the [Buildpack Specification](https://github.com/buildpacks/spec/blob/main/buildpack.md), +which defines the contract between buildpacks and the lifecycle. + + + +A buildpack must contain three files: + +* `buildpack.toml` +* `bin/detect` +* `bin/build` + +The two files in `bin/` must be executable. +They can be shell scripts written in a language like Bash, +or they can be executables compiled from a language like Go. + +## `buildpack.toml` + +A buildpack must contain a `buildpack.toml` file in its root directory. + +### Example + +``` +api = "0.10" + +[buildpack] +id = "example.com/python" +version = "1.0" + +# Targets the buildpack will work with +[[targets]] +os = "linux" + +# Stacks (deprecated) the buildpack will work with +[[stacks]] +id = "io.buildpacks.stacks.jammy" +``` + +For more information, see [buildpack config](/docs/reference/config/buildpack-config). + +## `bin/detect` + +### Usage + +``` +bin/detect +``` + +### Summary + +`bin/detect` is used to determine if a buildpack can work with a given codebase. +It will often check for the existence of a particular file, +or some configuration indicating what kind of application has been provided. + +Two environment variables identify important file system paths: + +* `CNB_PLATFORM_DIR` - a directory containing platform provided configuration, such as environment variables. +* `CNB_BUILD_PLAN_PATH` - a path to a file containing the [build plan]. + +In addition, the working directory for `bin/detect` is the application directory. + +`bin/detect` must return an exit code of `0` if the codebase can be serviced by this buildpack, +and `100` if it cannot. +Other exit codes indicate an error during detection. + +### Example + +This is a simple example of a buildpack that detects a Python application +by checking for the presence of a `requirements.txt` file: + +``` +#!/bin/sh + +if [ -f requirements.txt ]; then + echo "Python Buildpack" + exit 0 +else + exit 100 +fi +``` + +## `bin/build` + +### Usage + +``` +bin/build +``` + +`bin/build` does (all or part of) the work of transforming application source code into a runnable artifact. +It will often resolve dependencies, install binary packages, and compile code. +Three environment variables identify important file system paths: + +* `CNB_LAYERS_DIR` - a directory that may contain subdirectories representing each layer created by the buildpack in the final image or build cache. +* `CNB_PLATFORM_DIR` - a directory containing platform provided configuration, such as environment variables. +* `CNB_BP_PLAN_PATH` - a path to a file containing the [build plan]. + +In addition, the working directory for `bin/build` is the application directory. + +All changes to the codebase in the working directory will be persisted in the final image, +along with any launch layers created in the `CNB_LAYERS_DIR`. + +It is important to note that multiple buildpacks may work together to create the final image, +each contributing a subset of the dependencies or configuration needed to run the application. +In this way, buildpacks are modular and composable. + +[build plan]: /docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan \ No newline at end of file diff --git a/content/docs/for-buildpack-authors/how-to/write-buildpacks/specify-launch-processes.md b/content/docs/for-buildpack-authors/how-to/write-buildpacks/specify-launch-processes.md index c02f7702d..6146d716a 100644 --- a/content/docs/for-buildpack-authors/how-to/write-buildpacks/specify-launch-processes.md +++ b/content/docs/for-buildpack-authors/how-to/write-buildpacks/specify-launch-processes.md @@ -1,6 +1,6 @@ +++ title="Specify process types" -weight=1 +weight=4 +++ One of the benefits of buildpacks is that they are multi-process - an image can have multiple entrypoints for each operational mode. diff --git a/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan.md b/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan.md index f65f14f2d..d214321ec 100644 --- a/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan.md +++ b/content/docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan.md @@ -1,10 +1,121 @@ +++ title="Use the build plan" -weight=99 +weight=2 +++ +The [Build Plan](https://github.com/buildpacks/spec/blob/main/buildpack.md#build-plan-toml) is a document that buildpacks can use to pass information between the `detect` and `build` phases, and between each other. +The build plan is passed (by the lifecycle) as a parameter to the `detect` and `build` binaries of each buildpack. + -This page is a stub! The CNB project is applying to [Google Season of Docs](https://developers.google.com/season-of-docs/docs/timeline) to receive support for improving our documentation. Please check back soon. +During the `detect` phase, each buildpack may write something it `requires` or `provides` (or both) into the Build Plan. +A buildpack can `require` or `provide` multiple dependencies, and even multiple groupings of dependencies (using `or` lists). +Additionally, multiple buildpacks may `require` or `provide` the same dependency. +For detailed information, consult the [spec](https://github.com/buildpacks/spec/blob/main/buildpack.md#buildpack-plan-toml). + +The lifecycle uses the Build Plan to determine whether a particular list of buildpacks can work together, +by seeing whether all dependencies required can be provided by that list. + +Later, during the `build` phase, each buildpack may read the Buildpack Plan (a condensed version of the Build Plan, composed by the lifecycle) to determine what it should do. + +Let's see how this works with an example. + +### Example: `node-engine` buildpack + +Let's walk through some possible cases a `node-engine` buildpack may consider: + +1. Nothing in the app explicitly calls out that it is needed +2. It is explicitly referred to in some configuration file + +We will also consider what an `NPM` and a `JVM` buildpack may do. + +#### Scenario 1: No Explicit Request + +A `node-engine` buildpack is always happy to `provide` the `node` dependency. The build plan it will write may look something like: +``` +[[provides]] +name = "node" +``` +> **NOTE:** If this was the only buildpack running, this would fail the `detect` phase. In order to pass, every `provides` must be matched up with a `requires`, whether in the same buildpack or in another buildpack. +> See the [spec](https://github.com/buildpacks/spec/blob/main/buildpack.md#phase-1-detection) for particulars on how ordering buildpacks can adjust detection results. + +#### Scenario 2: One Version Requested + +During the `detect` phase, the `node-engine` buildpack sees in one configuration file (e.g. a `.nvmrc` file in the app directory) that `node v10.x` is explicitly requested by the application. Seeing that, it may write the below text to the build plan: +``` +[[provides]] +name = "node" + +[[requires]] +name = "node" +version = "10.x" + +[requires.metadata] +version-source = ".nvmrc" +``` + +As always, the buildpack `provides` `node`. In this particular case, a version of `node` (`10.x`) is being requested in a configuration file (`.nvmrc`). The buildpack chooses to add an additional piece of metadata (`version-source`), so that it can understand where that request came from. + +#### NPM Buildpack + +`NPM` is the default package manager for `node`. A NPM Buildpack may ensure that all the packages for the application are present (by running `npm install`), and perhaps cache those packages as well, to optimize future builds. + +NPM is typically distributed together with node. As a result, a NPM buildpack may require `node`, but not want to `provide` it, trusting that the `node-engine` buildpack will be in charge of `providing` `node`. + +The NPM buildpack could write the following to the build plan, if the buildpack sees that `npm` is necessary (e.g., it sees a `package.json` file in the app directory): +``` +[[requires]] +name = "node" +``` + +If, looking in the `package.json` file, the NPM buildpack sees a specific version of `node` requested in the [engines](https://docs.npmjs.com/files/package.json#engines) field (e.g. `14.1`), it may write the following to the build plan: +``` +[[requires]] +name = "node" +version = "14.1" + +[requires.metadata] +version-source = "package.json" +``` + +> **NOTE:** As above, if this was the only buildpack running, this would fail the `detect` phase. In order to pass, every `provides` must be matched up with a `requires`, whether in the same buildpack or in another buildpack. +> See the [spec](https://github.com/buildpacks/spec/blob/main/buildpack.md#phase-1-detection) for particulars on how ordering buildpacks can adjust detection results. + +However, if the NPM Buildpack was run together with the Node Engine buildpack (which `provides` `node`), the lifecycle will see that all requirements are fulfilled, and select that group as the correct set of buildpacks. + +### Example: JVM buildpack + +Java is distributed in two formats - the `jdk` (Java Development Kit), which allows for compilation and running of Java programs, and the `jre` (Java Runtime Environment, which allows for running compiled Java programs). +A very naive implementation of the buildpack may have it write several `provides` options to the build plan, detailing everything that it can provide, +while later buildpacks would figure out based on the application which options it requires, and would `require` those. +In this particular case, we can use the `or` operator to present different possible build plans the buildpack can follow: + +``` +# option 1 (`jre` and `jdk`) +[[provides]] +name = "jre" + +[[provides]] +name = "jdk" + +# option 2 (or just `jdk`) +[[or]] +[[or.provides]] +name = "jdk" + +# option 3 (or just `jre`) +[[or]] +[[or.provides]] +name = "jre" +``` + +The buildpack gives three options to the lifecycle: +* It can provide a standalone `jre` +* It can provide a standalone `jdk` +* It can provide both the `jdk` and `jre` + +As with the other buildpacks, this alone will not be sufficient for the lifecycle. However, other buildpacks that follow may `require` certain things. -If you are familiar with this content and would like to make a contribution, please feel free to open a PR :) +For example, another buildpack may look into the application and, seeing that it is a Java executable, `require` the `jre` in order to run it. +When the lifecycle analyzes the results of the `detect` phase, it will see that there is a buildpack which provides `jre`, and a buildpack that requires `jre`, +and will therefore conclude that those options represent a valid set of buildpacks. diff --git a/content/docs/for-buildpack-authors/tutorials/basic-buildpack/04_build-app.md b/content/docs/for-buildpack-authors/tutorials/basic-buildpack/04_build-app.md index 5811d265e..a9ccaa9bc 100644 --- a/content/docs/for-buildpack-authors/tutorials/basic-buildpack/04_build-app.md +++ b/content/docs/for-buildpack-authors/tutorials/basic-buildpack/04_build-app.md @@ -110,4 +110,4 @@ A new image named `test-node-js-app` was created in your Docker daemon with a la Next Step -[layers-dir]: /docs/reference/spec/buildpack-api/#layers +[layers-dir]: /docs/for-buildpack-authors/how-to/write-buildpacks/create-layer diff --git a/content/docs/for-buildpack-authors/tutorials/basic-extension/03_building-blocks-extension.md b/content/docs/for-buildpack-authors/tutorials/basic-extension/03_building-blocks-extension.md index b069a628b..6efc87712 100644 --- a/content/docs/for-buildpack-authors/tutorials/basic-extension/03_building-blocks-extension.md +++ b/content/docs/for-buildpack-authors/tutorials/basic-extension/03_building-blocks-extension.md @@ -34,7 +34,7 @@ You should see something akin to the following: API except where noted. Consult the [spec](https://github.com/buildpacks/spec/blob/main/image_extension.md) for further details. * `./bin/detect` is invoked during the `detect` phase. It analyzes application source code to determine if the extension - is needed and contributes [build plan](/docs/reference/spec/buildpack-api/#build-plan) entries (much like a + is needed and contributes [build plan] entries (much like a buildpack `./bin/detect`). Just like for buildpacks, a `./bin/detect` that exits with code `0` is considered to have passed detection, and fails otherwise. * `./bin/generate` is invoked during the `generate` phase (a new lifecycle phase that happens after `detect`). It @@ -51,3 +51,5 @@ For guidance around writing extensions and more advanced use cases, see [here](/ Next Step + +[build plan]: /docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan diff --git a/content/docs/reference/config/_index.md b/content/docs/reference/config/_index.md index 59ad01236..f52b1538c 100644 --- a/content/docs/reference/config/_index.md +++ b/content/docs/reference/config/_index.md @@ -1,5 +1,4 @@ +++ title="Configuration" include_summaries=true - +++ \ No newline at end of file diff --git a/content/docs/reference/config/builder-config.md b/content/docs/reference/config/builder-config.md index 3fb0529ef..261160c89 100644 --- a/content/docs/reference/config/builder-config.md +++ b/content/docs/reference/config/builder-config.md @@ -1,12 +1,16 @@ +++ title="builder.toml" -summary="Schema of the builder config file." aliases=[ "/docs/reference/builder-config/" ] +weight=2 +++ -A [builder][builder] configuration schema is as follows: +The builder config file is used for creating [builders][builder]. + + + +The schema is as follows: - #### `description` _(string, optional)_ A human-readable description of the builder, to be shown in `builder inspect` output @@ -26,7 +30,7 @@ A [builder][builder] configuration schema is as follows: - #### `order` _(list, required)_ A list of buildpack groups. This list determines the order in which groups of buildpacks - will be tested during detection. Detection is a phase of the [lifecycle][lifecycle] where + will be tested during detection. Detection is a phase of the [lifecycle] where buildpacks are tested, one group at a time, for compatibility with the provided application source code. The first group whose non-optional buildpacks all pass detection will be the group selected for the remainder of the build. Each group currently contains a single required field: @@ -85,7 +89,7 @@ A [builder][builder] configuration schema is as follows: [Run image mirrors](/docs/for-app-developers/concepts/base-images/run#run-image-mirrors) for the stack - #### `lifecycle` _(optional)_ - The [lifecycle][lifecycle] to embed into the builder. It must contain **at most one** the following fields: + The [lifecycle] to embed into the builder. It must contain **at most one** the following fields: - **`version`** _(string, optional)_\ The version of the lifecycle (semver format) to download. If specified, `uri` must not be provided. diff --git a/content/docs/reference/config/buildpack-config.md b/content/docs/reference/config/buildpack-config.md new file mode 100644 index 000000000..058944bfd --- /dev/null +++ b/content/docs/reference/config/buildpack-config.md @@ -0,0 +1,112 @@ ++++ +title="buildpack.toml" +weight=3 ++++ + +The buildpack configuration file is a necessary component of a [buildpack]. + + + +The schema is as follows: + +- **`api`** _(string, required, current: `0.10`)_\ + The Buildpack API version the buildpack adheres to. Used to ensure [compatibility](/docs/reference/spec/buildpack-api#api-compatibility) against + the [lifecycle]. + + > Not to be confused with Cloud Foundry or Heroku buildpack versions. + > This version pertains to the interface between the [buildpack] and the [lifecycle] of Cloud Native Buildpacks. + +- **`buildpack`** _(required)_\ + Information about the buildpack. + + - **`id`** _(string, required)_\ + A globally unique identifier. + + - **`version`** _(string, required)_\ + The version of the buildpack. + + - **`name`** _(string, required)_\ + Human readable name. + + - **`clear-env`** _(boolean, optional, default: `false`)_\ + Clears user-defined environment variables when `true` on executions of `bin/detect` and `bin/build`. + + - **`homepage`** _(string, optional)_\ + Buildpack homepage. + + - **`description`** _(string, optional)_\ + A short description of the buildpack. + + - **`keywords`** _(string(s), optional)_\ + Keywords to help locate the buildpack. These can be useful if publishing to the [Buildpack Registry](https://registry.buildpacks.io/). + + - **`sbom-formats`** _(string(s), optional)_\ + SBOM formats output by the buildpack. Supported values are the following media types: `application/vnd.cyclonedx+json`, `application/spdx+json`, and `application/vnd.syft+json`. + + - **`licenses`** _(list, optional)_\ + A list of licenses pertaining to the buildpack. + + - **`type`** _(string, optional)_\ + The type of the license. This may use the [SPDX 2.1 license expression](https://spdx.org/spdx-specification-21-web-version), but it is not limited to identifiers in the [SPDX Licenses List](https://spdx.org/licenses/). If the buildpack is using a nonstandard license, then the `uri` key may be specified in lieu of or in addition to `type` to point to the license. + + - **`uri`** _(string, optional)_\ + A URL or path to the license. + +- **`targets`** _(list, optional)_\ + A list of targets supported by the buildpack. + When no targets are specified, the `os`/`arch` will be inferred from the contents of the `./bin` directory + (`./bin/build` implies `linux`/`amd64` and `./bin/build.bat` implies `windows`/`amd64`). + For each target, all fields are optional (though at least one should be provided). + _Cannot be used in conjunction with `order` list._ + + - **`os`** _(string, optional)_\ + The supported operating system name. + + - **`arch`** _(string, optional)_\ + The supported architecture. + + - **`variant`** _(string, optional)_\ + The supported architecture variant. + + - **`targets.distros`** _(optional)_\ + A list of supported distributions for the given operating system, architecture, and architecture variant. + + - **`name`** _(string, optional)_\ + The supported operating system distribution name. + + - **`version`** _(string, optional)_\ + The supported operating system distribution version. + +- **`stacks`** _(list, deprecated, optional)_\ + A list of stacks supported by the buildpack. + _Cannot be used in conjunction with `order` list._ + + - **`id`** _(string, required)_\ + The id of the supported stack. + + - **`mixins`** _(string list, required)_\ + A list of mixins required on the stack images. + +- **`order`** _(list, optional)_\ + A list of buildpack groups for the purpose of creating a [meta-buildpack][meta-buildpack]. This list determines the + order in which groups of buildpacks will be tested during detection. _If omitted, `targets` or `stacks` list must be present. + Cannot be used in conjunction with `targets` or `stacks` list._ + + - **`group`** _(list, required)_\ + A list of buildpack references. + + - **`id`** _(string, required)_\ + The identifier of a buildpack being referred to. + Buildpacks with the same ID may appear in multiple groups at once but never in the same group. + + - **`version`** _(string, required)_\ + The version of the buildpack being referred to. + + - **`optional`** _(boolean, optional, default: `false`)_\ + Whether this buildpack is optional during detection. + +- **`metadata`** _(any, optional)_\ + Arbitrary data for buildpack. + +[buildpack]: /docs/for-buildpack-authors/concepts/buildpack +[lifecycle]: /docs/for-buildpack-authors/concepts/lifecycle-phases \ No newline at end of file diff --git a/content/docs/reference/config/package-config.md b/content/docs/reference/config/package-config.md index d89ecc8d5..e48d569e8 100644 --- a/content/docs/reference/config/package-config.md +++ b/content/docs/reference/config/package-config.md @@ -1,12 +1,16 @@ +++ title="package.toml" -summary="Schema of the buildpack package config file." aliases=[ "/docs/reference/package-config/", ] +weight=4 +++ -A [buildpackage][package] configuration schema is as follows: +The package config file is used for packaging buildpacks for distribution as OCI images or tar files. + + + +The schema is as follows: - #### `buildpack` _(required)_ The buildpack to package. It must contain the following field: @@ -33,4 +37,4 @@ You can view [sample buildpackages](https://github.com/buildpacks/samples/tree/m [package]: /docs/for-platform-operators/concepts/buildpack#distribution [supported-archives]: /docs/reference/builder-config#supported-archives -[order-group]: /docs/reference/spec/buildpack-api/#schema +[order-group]: https://github.com/buildpacks/spec/blob/main/buildpack.md#order-resolution diff --git a/content/docs/reference/config/project-descriptor.md b/content/docs/reference/config/project-descriptor.md index a40272d65..e389edff0 100644 --- a/content/docs/reference/config/project-descriptor.md +++ b/content/docs/reference/config/project-descriptor.md @@ -1,18 +1,22 @@ +++ title="project.toml" -summary="Schema of the project descriptor file." aliases=[ "/docs/reference/project-descriptor/" ] +weight=1 +++ -A project descriptor allows users to detail configuration for apps, services, functions and buildpacks. It should, by -default, be named `project.toml`, though users can name it differently, and pass the filename to `pack` by calling +The project descriptor file allows app developers to provide configuration for apps, services, functions and buildpacks. + + + +It should, by default, be named `project.toml`, though users can name it differently, and pass the filename to `pack` by calling + ```shell script $ pack build --descriptor ``` -The schema for the `project descriptor` is: +The schema is as follows: - #### `_` _(table, optional)_ A configuration table for a project. diff --git a/content/docs/reference/spec/_index.md b/content/docs/reference/spec/_index.md index af9fd6bcc..5960f9090 100644 --- a/content/docs/reference/spec/_index.md +++ b/content/docs/reference/spec/_index.md @@ -4,11 +4,10 @@ include_summaries=true expand=true +++ -This section provides an overview of the Cloud Native Buildpack API specification. +The Cloud Native Buildpacks specification defines the APIs that buildpacks, platforms, and the lifecycle must implement. -Most buildpack users won't need this information unless they are writing a buildpack or -a platform that supports buildpacks. +Most buildpack users won't need this information unless they are writing a buildpack or a platform that supports buildpacks. -The Cloud Native Buildpack API specification consists of the following parts: \ No newline at end of file +The specification consists of the following: diff --git a/content/docs/reference/spec/buildpack-api.md b/content/docs/reference/spec/buildpack-api.md index 86a0bca4f..ce61e14f0 100644 --- a/content/docs/reference/spec/buildpack-api.md +++ b/content/docs/reference/spec/buildpack-api.md @@ -1,394 +1,27 @@ -+++ -title="Buildpack API" ++++ title="Buildpack API" aliases=[ - "/docs/reference/buildpack-api/" +"/docs/reference/buildpack-api/" ] +++ -This specification defines the interface between a buildpack and the environment that runs it. -This API will be used by buildpack authors. +The Buildpack API specifies the interface between a [lifecycle] program and one or more [buildpacks][buildpack]. -A buildpack must contain three files: - -* `buildpack.toml` -* `bin/detect` -* `bin/build` - -The two files in `bin/` must be executable. They can be shell scripts written in a language like Bash or they -can be executables compiled from a language like Go. - -## `bin/detect` - -### Usage - -``` -bin/detect -``` - -### Summary - -This entrypoint is used to determine if a buildpack should -run against a given codebase. It will often check for the existence of a particular -file or some configuration indicating what kind of application has been provided. -Two environment variables identify important file system paths: - -* `CNB_PLATFORM_DIR` - a directory containing platform provided configuration, such as environment variables. -* `CNB_BUILD_PLAN_PATH` - a path to a file containing the [Build Plan](#build-plan). - -In addition, the working directory is defined as the location of the codebase -the buildpack will execute against. - -The executable must return an exit code of `0` if the codebase can be serviced by this buildpack, and `100` if it cannot. -Other exit codes indicate an error during detection. - -### Example - -This is a simple example of a buildpack that detects a Python application by -checking for the presence of a `requirements.txt` file: - -``` -#!/bin/sh - -if [ -f requirements.txt ]; then - echo "Python Buildpack" - exit 0 -else - exit 100 -fi -``` - -## `bin/build` - -### Usage - -``` -bin/build -``` - -This entrypoint transforms a codebase. -It will often resolve dependencies, install binary packages, and compile code. -Three environment variables identify important file system paths: - -* `CNB_LAYERS_DIR` - a directory that may contain subdirectories representing each layer created by the buildpack in the final image or build cache. -* `CNB_PLATFORM_DIR` - a directory containing platform provided configuration, such as environment variables. -* `CNB_BP_PLAN_PATH` - a path to a file containing the [Build Plan](#build-plan). - -In addition, the working directory is defined as the location of the codebase -this buildpack will execute against. - -All changes to the codebase in the working directory will be included in the final -image, along with any launch layers created in the `CNB_LAYERS_DIR`. - -#### Layers - -Each directory created by the buildpack under the `CNB_LAYERS_DIR` can be used for any -of the following purposes: - -* Launch - the directory will be included in the run image as a single layer -* Cache - the directory will be included in the cache -* Build - the directory will be accessible by subsequent buildpacks - -A buildpack defines how a layer will by used by creating a `.toml` with -a name matching the directory it describes in the `CNB_LAYERS_DIR`. For example, a -buildpack might create a `$CNB_LAYERS_DIR/python` directory and a `$CNB_LAYERS_DIR/python.toml` -with the following contents: - -``` -launch = true -cache = true -build = true -``` - -In this example, the `python` directory will be included in the run image, -cached for future builds, and will be accessible to subsequent buildpacks. - -### Example - -This is a simple example of a buildpack that runs Python's `pip` package manager -to resolve dependencies: - -``` -#!/bin/sh - -PIP_LAYER="$CNB_LAYERS_DIR/pip" -mkdir -p "$PIP_LAYER/modules" "$PIP_LAYER/env" - -pip install -r requirements.txt -t "$PIP_LAYER/modules" \ - --install-option="--install-scripts=$PIP_LAYER/bin" \ - --exists-action=w --disable-pip-version-check --no-cache-dir - -echo "launch = true" > "$PIP_LAYER.toml" -``` - -## `buildpack.toml` - -A buildpack must contain a `buildpack.toml` file in its root directory. - - -### Example - -``` -api = "0.10" - -[buildpack] -id = "example.com/python" -version = "1.0" - -# Targets the buildpack will work with -[[targets]] -os = "linux" - -# Stacks (deprecated) the buildpack will work with -[[stacks]] -id = "io.buildpacks.stacks.jammy" -``` - -### Schema - -The schema is as follows: -- **`api`** _(string, required, current: `0.10`)_\ - The Buildpack API version the buildpack adheres to. Used to ensure [compatibility](#api-compatibility) against - the [lifecycle][lifecycle]. - - > Not to be confused with Cloud Foundry or Heroku buildpack versions. This version pertains to the interface - > between the [buildpack][buildpack] and the [lifecycle][lifecycle] of Cloud Native Buildpacks. - -- **`buildpack`** _(required)_\ - Information about the buildpack. - - - **`id`** _(string, required)_\ - A globally unique identifier. - - - **`version`** _(string, required)_\ - The version of the buildpack. - - - **`name`** _(string, required)_\ - Human readable name. - - - **`clear-env`** _(boolean, optional, default: `false`)_\ - Clears user-defined environment variables when `true` on executions of `bin/detect` and `bin/build`. - - - **`homepage`** _(string, optional)_\ - Buildpack homepage. - - - **`description`** _(string, optional)_\ - A short description of the buildpack. - - - **`keywords`** _(string(s), optional)_\ - Keywords to help locate the buildpack. These can be useful if publishing to the [Buildpack Registry](https://registry.buildpacks.io/). - - - **`sbom-formats`** _(string(s), optional)_\ - SBOM formats output by the buildpack. Supported values are the following media types: `application/vnd.cyclonedx+json`, `application/spdx+json`, and `application/vnd.syft+json`. - - - **`licenses`** _(list, optional)_\ - A list of licenses pertaining to the buildpack. - - - **`type`** _(string, optional)_\ - The type of the license. This may use the [SPDX 2.1 license expression](https://spdx.org/spdx-specification-21-web-version), but it is not limited to identifiers in the [SPDX Licenses List](https://spdx.org/licenses/). If the buildpack is using a nonstandard license, then the `uri` key may be specified in lieu of or in addition to `type` to point to the license. - - - **`uri`** _(string, optional)_\ - A URL or path to the license. - -- **`targets`** _(list, optional)_\ - A list of targets supported by the buildpack. - When no targets are specified, the `os`/`arch` will be inferred from the contents of the `./bin` directory - (`./bin/build` implies `linux`/`amd64` and `./bin/build.bat` implies `windows`/`amd64`). - For each target, all fields are optional (though at least one should be provided). - _Cannot be used in conjunction with `order` list._ - - - **`os`** _(string, optional)_\ - The supported operating system name. - - - **`arch`** _(string, optional)_\ - The supported architecture. - - - **`variant`** _(string, optional)_\ - The supported architecture variant. - - - **`targets.distros`** _(optional)_\ - A list of supported distributions for the given operating system, architecture, and architecture variant. - - - **`name`** _(string, optional)_\ - The supported operating system distribution name. - - - **`version`** _(string, optional)_\ - The supported operating system distribution version. - -- **`stacks`** _(list, deprecated, optional)_\ - A list of stacks supported by the buildpack. - _Cannot be used in conjunction with `order` list._ - - - **`id`** _(string, required)_\ - The id of the supported stack. - - - **`mixins`** _(string list, required)_\ - A list of mixins required on the stack images. - -- **`order`** _(list, optional)_\ - A list of buildpack groups for the purpose of creating a [meta-buildpack][meta-buildpack]. This list determines the - order in which groups of buildpacks will be tested during detection. _If omitted, `targets` or `stacks` list must be present. - Cannot be used in conjunction with `targets` or `stacks` list._ - - - **`group`** _(list, required)_\ - A list of buildpack references. - - - **`id`** _(string, required)_\ - The identifier of a buildpack being referred to. - Buildpacks with the same ID may appear in multiple groups at once but never in the same group. - - - **`version`** _(string, required)_\ - The version of the buildpack being referred to. - - - **`optional`** _(boolean, optional, default: `false`)_\ - Whether this buildpack is optional during detection. - -- **`metadata`** _(any, optional)_\ - Arbitrary data for buildpack. - -## Build Plan -The [Build Plan](https://github.com/buildpacks/spec/blob/main/buildpack.md#build-plan-toml) is a document the buildpacks can use to pass information between the [detect](#bindetect) and [build](#bindetect) phases. The build plan is passed (by the lifecycle) as a parameter to the `detect` and `build` binaries of the buildpack. -* During the `detect` phase, the buildpack(s) may write something it `requires` or `provides` (or both) into the Build Plan. -* During the `build` phase, the buildpack(s) may read the Buildpack Plan (a condensed version of the Build Plan, composed by the lifecycle) to determine what it should do, and refine the Buildpack Plan with more exact metadata (eg: what version dependency it requires). - -A buildpack can `require` or `provide` multiple dependencies, and even multiple groupings of dependencies (using `or` lists). Additionally, multiple buildpacks may `require` or `provide` the same dependency. - -The lifecycle uses the Build Plan as one element in deciding whether or not a particular list of buildpacks is appropriate, by seeing whether all dependencies required can be provided by that list. - -### Example -Let's walk through some possible cases a `node-engine` buildpack may consider: - -1. Nothing in the app explicitly calls out that it is needed -2. It is explicitly referred to in some configuration file - -We will also consider what a `NPM` and a `JVM` buildpack may do. - -#### 1. No Explicit Request -A `node-engine` buildpack is always happy to `provide` the `node` dependency. The build plan it will write may look something like: -``` -[[provides]] -name = "node" -``` -> **NOTE:** If this was the only buildpack running, this would fail the `detect` phase. In order to pass, every `provides` must be matched up with a `requires`, whether in the same buildpack or in another buildpack. See the [spec](https://github.com/buildpacks/spec/blob/main/buildpack.md#phase-1-detection) for particulars on how ordering buildpacks can adjust detection results. - -#### 2. One Version Requested -During the `detect` phase, the `node-engine` buildpack sees in one configuration file (e.g. a `.nvmrc` file in the app directory) that `node v10.x` is explicitly requested by the application. Seeing that, it may write the below text to the build plan: -``` -[[provides]] -name = "node" - -[[requires]] -name = "node" -version = "10.x" - -[requires.metadata] -version-source = ".nvmrc" -``` - -As always, the buildpack `provides` `node`. In this particular case, a version of `node` (`10.x`) is being requested in a configuration file (`.nvmrc`). The buildpack chooses to add an additional piece of metadata (`version-source`), so that it can understand where that request came from. - -#### NPM Buildpack -`NPM` is the default package manager for `node`. A NPM Buildpack may ensure that all the packages for the application are present (by running `npm install`), and perhaps cache those packages as well, to optimize future builds. - -NPM is typically distributed together with node. As a result, a NPM buildpack may require `node`, but not want to `provide` it, trusting that the `node-engine` buildpack will be in charge of `providing` `node`. - -The NPM buildpack could write the following to the build plan, if the buildpack sees that `npm` is necessary (e.g., it sees a `package.json` file in the app directory): -``` -[[requires]] -name = "node" -``` - -If, looking in the `package.json` file, the NPM buildpack sees a specific version of `node` requested in the [engines](https://docs.npmjs.com/files/package.json#engines) field (e.g. `14.1`), it may write the following to the build plan: -``` -[[requires]] -name = "node" -version = "14.1" - -[requires.metadata] -version-source = "package.json" -``` - -> **NOTE:** As above, if this was the only buildpack running, this would fail the `detect` phase. In order to pass, every `provides` must be matched up with a `requires`, whether in the same buildpack or in another buildpack. See the [spec](https://github.com/buildpacks/spec/blob/main/buildpack.md#phase-1-detection) for particulars on how ordering buildpacks can adjust detection results. - -However, if the NPM Buildpack was run together with the Node Engine buildpack (which `provides` `node`), the lifecycle will see that all requirements are fulfilled, and select that group as the correct set of buildpacks. - -#### Possible JVM Buildpack -Java is distributed in two formats - the `jdk` (Java Development Kit), which allows for compilation and running of Java programs, and the `jre` (Java Runtime Environment, which allows for running compiled Java programs). A very naive implementation of the buildpack may have it write several `provides` options to the build plan, detailing everything that it can provide, while later buildpacks would figure out based on the application which options it requires, and would `require` those. In this particular case, we can use the `or` operator to present different possible build plans the buildpack can follow: - -``` -# option 1 (`jre` and `jdk`) -[[provides]] -name = "jre" - -[[provides]] -name = "jdk" - -# option 2 (or just `jdk`) -[[or]] -[[or.provides]] -name = "jdk" - -# option 3 (or just `jre`) -[[or]] -[[or.provides]] -name = "jre" -``` - -The buildpack gives three options to the lifecycle: -* It can provide a standalone `jre` -* It can provide a standalone `jdk` -* It can provide both the `jdk` and `jre` - -As with the other buildpacks, this alone will not be sufficient for the lifecycle. However, other buildpacks that follow may `require` certain things. For example, another buildpack may look into the application and, seeing that it is a Java executable, `require` the `jre` in order to run it. When the lifecycle analyzes the results of the detect phase, it will see that there is a buildpack which provides `jre`, and a buildpack that requires `jre`, and will therefore conclude that those options represent a valid set of buildpacks. - -### Schema -- **`provides`** _(list, optional)_\ - A list of dependencies which the buildpack provides. - - **`name`** _(string, required)_\ - The name of the provided dependency. - -- **`requires`** _(list, optional)_\ - A list of dependencies which the buildpack requires. - - **`name`** _(string, required)_\ - The name of the required dependency. - - - **`version`** _(string, optional)_\ - The version of the dependency required. - - - **`metadata`** _(object, optional)_\ - Any additional key-value metadata you wish to store. - -- **`or`** _(array, optional)_\ - A list of alternate requirements which the buildpack provides/requires. Each `or` array must contain a valid Build Plan (with `provides` and `requires`) - -For more information, see the [Build Plan](https://github.com/buildpacks/spec/blob/main/buildpack.md#buildpack-plan-toml) section of the spec. - ## API Compatibility -**Given** the buildpack and lifecycle both declare a **Buildpack API version** in format:\ -`.` - -**Then** a buildpack and a lifecycle are considered compatible if all the following conditions are true: +A [buildpack] only ever implements one Buildpack API version at a time. +The implemented Buildpack API version can be found in the `buildpack.toml` file in the buildpack's root directory, +or in a label on a buildpack package. -- If versions are pre-release, where `` is `0`, then ``s must match. -- If versions are stable, where `` is greater than `0`, then `` of the buildpack must be less than -or equal to that of the lifecycle. -- ``s must always match. +A [lifecycle] may (and usually does) support more than one Buildpack API version at a time. +The supported Buildpack API version(s) can be found in the `lifecycle.toml` file in a lifecycle tarball, +or in a label on the [lifecycle image](https://hub.docker.com/r/buildpacksio/lifecycle). -
-For example, +A lifecycle "supports" a buildpack if they both declare support for the same Buildpack API version in format: `.`. -| Buildpack _implements_ Buildpack API | Lifecycle _implements_ Buildpack API | Compatible? | -| ------------------------------------ | ------------------------------------ | ------------------------------------- | -| `0.2` | `0.2` | yes | -| `1.1` | `1.1` | yes | -| `1.2` | `1.3` | yes | -| `0.2` | `0.3` | no | -| `0.3` | `0.2` | no | -| `1.3` | `1.2` | no | -| `1.3` | `2.3` | no | -| `2.3` | `1.3` | no | +Two buildpacks of different Buildpack API versions can participate in the same build, +provided they are both supported by the lifecycle. ## Further Reading @@ -396,4 +29,3 @@ You can read the complete [Buildpack API specification on Github](https://github [buildpack]: /docs/for-platform-operators/concepts/buildpack/ [lifecycle]: /docs/for-platform-operators/concepts/lifecycle/ -[meta-buildpack]: /docs/for-platform-operators/concepts/composite-buildpack