Skip to content

Commit 00dad77

Browse files
authored
Merge pull request #665 from buildpacks/breakup-buildpack-api
Break up Buildpack API section into separate "how to" pages
2 parents d1e1af6 + 8305eb8 commit 00dad77

File tree

18 files changed

+440
-410
lines changed

18 files changed

+440
-410
lines changed

content/docs/.common/concepts/extension.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ provide. By contrast, Dockerfiles are the most-used and best-understood mechanis
3434
installing OS-level dependencies for containers.
3535

3636
The CNB Dockerfiles feature allows Dockerfiles to "provide" dependencies that buildpacks "require" through a
37-
shared [build plan](/docs/reference/spec/buildpack-api/#build-plan), by introducing the concept of image extensions.
37+
shared [build plan], by introducing the concept of image extensions.
3838

3939
## What do they look like?
4040

@@ -67,7 +67,7 @@ The extension determines if it is needed or not.
6767

6868
Like buildpacks, extensions participate in the `detect` phase - analyzing application source code to determine if they
6969
are needed. During `detect`, extensions can contribute to
70-
the [build plan](/docs/reference/spec/buildpack-api/#build-plan) - recording dependencies that they are able to "
70+
the [build plan] - recording dependencies that they are able to "
7171
provide" (though unlike buildpacks, they can't "require" anything).
7272

7373
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
8080

8181
For more information and to see a build in action,
8282
see [authoring an image extension](/docs/for-buildpack-authors/tutorials/basic-extension).
83+
84+
[build plan]: /docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan

content/docs/for-buildpack-authors/concepts/caching-strategies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ There are three types of layers that can be contributed to an image
1414

1515
* `build` layers -- the directory will be accessible by subsequent buildpacks,
1616
* `cache` layers -- the directory will be included in the cache,
17-
* `launch` layers -- the directory will be included in the run image as a single layer,
17+
* `launch` layers -- the directory will be included in the final app image as a single layer,
1818

1919
In this section we look at caching each layer type.
2020

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
+++
2+
title="Craft a buildpack order"
3+
weight=99
4+
+++
5+
6+
<!--more-->
7+
8+
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.
9+
10+
If you are familiar with this content and would like to make a contribution, please feel free to open a PR :)

content/docs/for-buildpack-authors/how-to/distribute-buildpacks/package-buildpack.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title="Package a buildpack or extension"
44
aliases=[
55
"/docs/buildpack-author-guide/package-a-buildpack"
66
]
7-
weight=5
7+
weight=4
88
summary="Learn how to package your buildpack or extension for distribution."
99
+++
1010

content/docs/for-buildpack-authors/how-to/write-buildpacks/add-sbom.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
+++
22
title="Provide a Software Bill-of-Materials"
3-
weight=2
3+
weight=5
44
+++
55

66
Buildpacks can provide a [Software `Bill-of-Materials`](https://en.wikipedia.org/wiki/Software_bill_of_materials) (SBOM)
Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,50 @@
11
+++
22
title="Create dependency layers"
3-
weight=99
3+
weight=3
44
+++
55

6+
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.
7+
68
<!--more-->
79

8-
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.
10+
That is, each directory can be used for any of the following purposes:
11+
12+
| Layer Type | |
13+
|------------|-------------------------------------------------------------------------------------------------------------|
14+
| `Launch` | the directory will be included in the **final app image** as a single layer |
15+
| `Cache` | the directory will be included in the **build cache** and restored to the `CNB_LAYERS_DIR` on future builds |
16+
| `Build` | the directory will be accessible to **buildpacks that follow** in the build (via the environment) |
17+
18+
A buildpack can control how a layer will be used by creating a `<layer>.toml` with a name matching the directory it describes in the `CNB_LAYERS_DIR`.
19+
20+
### Example
21+
22+
A buildpack might create a `$CNB_LAYERS_DIR/python` directory and a `$CNB_LAYERS_DIR/python.toml` with the following contents:
23+
24+
```
25+
launch = true
26+
cache = true
27+
build = true
28+
```
29+
30+
In this example:
31+
* the final app image will contain a layer with `python`, as this is needed to run the app
32+
* the `$CNB_LAYERS_DIR/python` directory will be pre-created for future builds, avoiding the need to re-download this large dependency
33+
* buildpacks that follow in the build will be able to use `python`
34+
35+
### Example
36+
37+
This is a simple `./bin/build` script for a buildpack that runs Python's `pip` package manager to resolve dependencies:
38+
39+
```
40+
#!/bin/sh
41+
42+
PIP_LAYER="$CNB_LAYERS_DIR/pip"
43+
mkdir -p "$PIP_LAYER/modules" "$PIP_LAYER/env"
44+
45+
pip install -r requirements.txt -t "$PIP_LAYER/modules" \
46+
--install-option="--install-scripts=$PIP_LAYER/bin" \
47+
--exists-action=w --disable-pip-version-check --no-cache-dir
948
10-
If you are familiar with this content and would like to make a contribution, please feel free to open a PR :)
49+
echo "launch = true" > "$PIP_LAYER.toml"
50+
```
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
+++
2+
title="Get started"
3+
weight=1
4+
+++
5+
6+
To write a buildpack, we follow the [Buildpack Specification](https://github.com/buildpacks/spec/blob/main/buildpack.md),
7+
which defines the contract between buildpacks and the lifecycle.
8+
9+
<!--more-->
10+
11+
A buildpack must contain three files:
12+
13+
* `buildpack.toml`
14+
* `bin/detect`
15+
* `bin/build`
16+
17+
The two files in `bin/` must be executable.
18+
They can be shell scripts written in a language like Bash,
19+
or they can be executables compiled from a language like Go.
20+
21+
## `buildpack.toml`
22+
23+
A buildpack must contain a `buildpack.toml` file in its root directory.
24+
25+
### Example
26+
27+
```
28+
api = "0.10"
29+
30+
[buildpack]
31+
id = "example.com/python"
32+
version = "1.0"
33+
34+
# Targets the buildpack will work with
35+
[[targets]]
36+
os = "linux"
37+
38+
# Stacks (deprecated) the buildpack will work with
39+
[[stacks]]
40+
id = "io.buildpacks.stacks.jammy"
41+
```
42+
43+
For more information, see [buildpack config](/docs/reference/config/buildpack-config).
44+
45+
## `bin/detect`
46+
47+
### Usage
48+
49+
```
50+
bin/detect
51+
```
52+
53+
### Summary
54+
55+
`bin/detect` is used to determine if a buildpack can work with a given codebase.
56+
It will often check for the existence of a particular file,
57+
or some configuration indicating what kind of application has been provided.
58+
59+
Two environment variables identify important file system paths:
60+
61+
* `CNB_PLATFORM_DIR` - a directory containing platform provided configuration, such as environment variables.
62+
* `CNB_BUILD_PLAN_PATH` - a path to a file containing the [build plan].
63+
64+
In addition, the working directory for `bin/detect` is the application directory.
65+
66+
`bin/detect` must return an exit code of `0` if the codebase can be serviced by this buildpack,
67+
and `100` if it cannot.
68+
Other exit codes indicate an error during detection.
69+
70+
### Example
71+
72+
This is a simple example of a buildpack that detects a Python application
73+
by checking for the presence of a `requirements.txt` file:
74+
75+
```
76+
#!/bin/sh
77+
78+
if [ -f requirements.txt ]; then
79+
echo "Python Buildpack"
80+
exit 0
81+
else
82+
exit 100
83+
fi
84+
```
85+
86+
## `bin/build`
87+
88+
### Usage
89+
90+
```
91+
bin/build
92+
```
93+
94+
`bin/build` does (all or part of) the work of transforming application source code into a runnable artifact.
95+
It will often resolve dependencies, install binary packages, and compile code.
96+
Three environment variables identify important file system paths:
97+
98+
* `CNB_LAYERS_DIR` - a directory that may contain subdirectories representing each layer created by the buildpack in the final image or build cache.
99+
* `CNB_PLATFORM_DIR` - a directory containing platform provided configuration, such as environment variables.
100+
* `CNB_BP_PLAN_PATH` - a path to a file containing the [build plan].
101+
102+
In addition, the working directory for `bin/build` is the application directory.
103+
104+
All changes to the codebase in the working directory will be persisted in the final image,
105+
along with any launch layers created in the `CNB_LAYERS_DIR`.
106+
107+
It is important to note that multiple buildpacks may work together to create the final image,
108+
each contributing a subset of the dependencies or configuration needed to run the application.
109+
In this way, buildpacks are modular and composable.
110+
111+
[build plan]: /docs/for-buildpack-authors/how-to/write-buildpacks/use-build-plan

content/docs/for-buildpack-authors/how-to/write-buildpacks/specify-launch-processes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
+++
22
title="Specify process types"
3-
weight=1
3+
weight=4
44
+++
55

66
One of the benefits of buildpacks is that they are multi-process - an image can have multiple entrypoints for each operational mode.
Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,121 @@
11
+++
22
title="Use the build plan"
3-
weight=99
3+
weight=2
44
+++
55

6+
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.
7+
The build plan is passed (by the lifecycle) as a parameter to the `detect` and `build` binaries of each buildpack.
8+
69
<!--more-->
710

8-
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.
11+
During the `detect` phase, each buildpack may write something it `requires` or `provides` (or both) into the Build Plan.
12+
A buildpack can `require` or `provide` multiple dependencies, and even multiple groupings of dependencies (using `or` lists).
13+
Additionally, multiple buildpacks may `require` or `provide` the same dependency.
14+
For detailed information, consult the [spec](https://github.com/buildpacks/spec/blob/main/buildpack.md#buildpack-plan-toml).
15+
16+
The lifecycle uses the Build Plan to determine whether a particular list of buildpacks can work together,
17+
by seeing whether all dependencies required can be provided by that list.
18+
19+
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.
20+
21+
Let's see how this works with an example.
22+
23+
### Example: `node-engine` buildpack
24+
25+
Let's walk through some possible cases a `node-engine` buildpack may consider:
26+
27+
1. Nothing in the app explicitly calls out that it is needed
28+
2. It is explicitly referred to in some configuration file
29+
30+
We will also consider what an `NPM` and a `JVM` buildpack may do.
31+
32+
#### Scenario 1: No Explicit Request
33+
34+
A `node-engine` buildpack is always happy to `provide` the `node` dependency. The build plan it will write may look something like:
35+
```
36+
[[provides]]
37+
name = "node"
38+
```
39+
> **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.
40+
> 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.
41+
42+
#### Scenario 2: One Version Requested
43+
44+
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:
45+
```
46+
[[provides]]
47+
name = "node"
48+
49+
[[requires]]
50+
name = "node"
51+
version = "10.x"
52+
53+
[requires.metadata]
54+
version-source = ".nvmrc"
55+
```
56+
57+
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.
58+
59+
#### NPM Buildpack
60+
61+
`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.
62+
63+
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`.
64+
65+
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):
66+
```
67+
[[requires]]
68+
name = "node"
69+
```
70+
71+
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:
72+
```
73+
[[requires]]
74+
name = "node"
75+
version = "14.1"
76+
77+
[requires.metadata]
78+
version-source = "package.json"
79+
```
80+
81+
> **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.
82+
> 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.
83+
84+
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.
85+
86+
### Example: JVM buildpack
87+
88+
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).
89+
A very naive implementation of the buildpack may have it write several `provides` options to the build plan, detailing everything that it can provide,
90+
while later buildpacks would figure out based on the application which options it requires, and would `require` those.
91+
In this particular case, we can use the `or` operator to present different possible build plans the buildpack can follow:
92+
93+
```
94+
# option 1 (`jre` and `jdk`)
95+
[[provides]]
96+
name = "jre"
97+
98+
[[provides]]
99+
name = "jdk"
100+
101+
# option 2 (or just `jdk`)
102+
[[or]]
103+
[[or.provides]]
104+
name = "jdk"
105+
106+
# option 3 (or just `jre`)
107+
[[or]]
108+
[[or.provides]]
109+
name = "jre"
110+
```
111+
112+
The buildpack gives three options to the lifecycle:
113+
* It can provide a standalone `jre`
114+
* It can provide a standalone `jdk`
115+
* It can provide both the `jdk` and `jre`
116+
117+
As with the other buildpacks, this alone will not be sufficient for the lifecycle. However, other buildpacks that follow may `require` certain things.
9118

10-
If you are familiar with this content and would like to make a contribution, please feel free to open a PR :)
119+
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.
120+
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`,
121+
and will therefore conclude that those options represent a valid set of buildpacks.

content/docs/for-buildpack-authors/tutorials/basic-buildpack/04_build-app.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,4 @@ A new image named `test-node-js-app` was created in your Docker daemon with a la
110110
<a href="/docs/for-buildpack-authors/tutorials/basic-buildpack/05_make-app-runnable" class="button bg-pink">Next Step</a>
111111
<!--+end+-->
112112

113-
[layers-dir]: /docs/reference/spec/buildpack-api/#layers
113+
[layers-dir]: /docs/for-buildpack-authors/how-to/write-buildpacks/create-layer

0 commit comments

Comments
 (0)