Skip to content

Commit

Permalink
Merge pull request #618 from buildpacks/add-targets
Browse files Browse the repository at this point in the history
Add targets and deprecate stacks
  • Loading branch information
AidanDelaney authored Oct 26, 2023
2 parents 966f944 + 2505b29 commit 8464a43
Show file tree
Hide file tree
Showing 26 changed files with 504 additions and 331 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Install pack
uses: buildpacks/github-actions/[email protected]
with:
pack-version: '0.30.0-rc1' # FIXME: update to 0.30.0 when available
pack-version: '0.31.0'
- name: Test
run: make test
env:
Expand Down
2 changes: 1 addition & 1 deletion content/docs/app-developer-guide/run-an-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Base Image:
Top Layer: sha256:700c764e7c5d5c75e6a0fc7d272b7e1c70ab327c03fbdf4abd9313e5ec3217f7
Run Images:
cnbs/sample-stack-run:alpine
cnbs/sample-base-run:alpine
Rebasable: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ You should see the following:
<!-- test:assert=contains;ignore-lines=... -->
```text
Run Images:
cnbs/sample-stack-run:jammy
cnbs/sample-base-run:jammy
...
Buildpacks:
Expand Down Expand Up @@ -55,9 +55,13 @@ api = "0.8"
version = "0.0.1"
sbom-formats = [ "application/vnd.cyclonedx+json" ]

# Stacks that the buildpack will work with
# Targets the buildpack will work with
[[targets]]
os = "linux"

# Stacks (deprecated) the buildpack will work with
[[stacks]]
id = "io.buildpacks.samples.stacks.jammy"
id = "*"
```

Then, in our buildpack implementation we will generate the necessary SBOM metadata:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ This command will create `ruby-buildpack` directory which contains `buildpack.to
### Additional Parameters
- `-a, --api` Buildpack API compatibility of the generated buildpack
- `-h, --help` Help for 'new'
- `--path` the location on the filesystem to generate the artifacts.
- `--stacks` Stack(s) this buildpack will be compatible with. Repeat for each stack in order, or supply once by comma-separated list
- `--path` the location on the filesystem to generate the artifacts
- `--stacks` Stacks (deprecated) the buildpack will work with
- `-V, --version` the version of the buildpack in buildpack.toml


Expand All @@ -48,13 +48,19 @@ api = "0.8"
id = "examples/ruby"
version = "0.0.1"

# Stacks that the buildpack will work with
# Targets the buildpack will work with
[[targets]]
os = "linux"

# Stacks (deprecated) the buildpack will work with
[[stacks]]
id = "io.buildpacks.samples.stacks.jammy"

```

You will notice two specific fields in the file: `buildpack.id` and `stack.id`. The buildpack ID is the way you will reference the buildpack when you create buildpack groups, builders, etc. The stack ID is the root file system in which the buildpack will be run. This example can be run on one of two different stacks, both based upon Ubuntu Bionic.
The buildpack ID is the way you will reference the buildpack when you create buildpack groups, builders, etc.
[Targets](/docs/concepts/components/targets/) identifies the kind of build and run base images the buildpack will work with.
The stack ID (deprecated) uniquely identifies a build and run image configuration the buildpack will work with. This example can be run on Ubuntu Jammy.

### `detect` and `build`

Expand Down
3 changes: 2 additions & 1 deletion content/docs/concepts/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ For example:

![builder](/docs/concepts/builder.svg)

[`Builders`](/docs/concepts/components/builder) are an ordered combination of [`buildpacks`](/docs/concepts/components/buildpack) with a base `build` image, a lifecycle, and reference to a `run image`. They take in your `app` source code and build the output `app image`. The `build` image provides the base environment for the `builder` (for eg. an Ubuntu Bionic OS image with build tooling) and a `run` image provides the base environment for the `app image` during runtime. A combination of a `build` image and a `run` image is called a [`stack`](/docs/concepts/components/stack).
[`Builders`](/docs/concepts/components/builder) are an ordered combination of [`buildpacks`](/docs/concepts/components/buildpack) with a base `build image`, a lifecycle, and reference to a `run image`.
They take in your `app` source code and build the output `app image`. The `build image` provides the base environment for the `builder` (for eg. an Ubuntu Bionic OS image with build tooling) and a `run image` provides the base environment for the `app image` during runtime.

Under the hood a builder uses the [`lifecycle`](/docs/concepts/components/lifecycle) to run the `detect` phase for all the `buildpacks` it contains in order and then proceeds to run the `build` phase of all the `buildpacks` that passed detection.

Expand Down
9 changes: 9 additions & 0 deletions content/docs/concepts/components/base-images/build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
+++
title="Build image"
weight=1
+++

## What is a build image?

The **build image** provides the base image from which the build environment is constructed.
The build environment is the containerized environment in which the [lifecycle][lifecycle] (and thereby [buildpacks][buildpack]) are executed.
41 changes: 41 additions & 0 deletions content/docs/concepts/components/base-images/run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
+++
title="Run image"
weight=2
+++

## What is a run image?

The **run image** provides the base image for application images.
The lifecycle requires a reference to a run image and (where necessary) possible run image mirrors in order to construct the application image.

### Run image mirrors

Run image mirrors provide alternate locations for run images, for use during `build` or `rebase`.
When running `build` with a builder containing run image mirrors, `pack` will select a run image
whose registry location matches that of the specified app image (if no registry host is specified in the image name,
DockerHub is assumed). This is useful when publishing the resulting app image (via the `--publish` flag or via
`docker push`), as the app's base image (i.e. run image) will be located on the same registry as the app image itself,
reducing the amount of data transfer required to push the app image.

In the following example, assuming a builder configured with the example TOML above, the selected run image will be
`registry.example.com/example/run`.

```bash
$ pack build registry.example.com/example/app
```

while naming the app without a registry specified, `example/app`, will cause `example/run` to be selected as the app's
run image.

```bash
$ pack build example/app
```

> For local development, it's often helpful to override the run image mirrors in a builder. For this, the
> `pack config run-image-mirrors` command can be used. This command does not modify the builder, and instead configures the
> local environment.
>
> To see what run images are configured for a builder, the
> `builder inspect` command can be used. `builder inspect` will output built-in and locally-configured run images for
> a given builder, along with other useful information. The order of the run images in the output denotes the order in
> which they will be matched during `build`.
6 changes: 3 additions & 3 deletions content/docs/concepts/components/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ aliases=[
A builder consists of the following components:

* [Buildpacks][buildpack]
* [Lifecycle][lifecycle]
* [Stack's][stack] build image
* A [lifecycle][lifecycle]
* A [build image](/docs/concepts/components/base-images/build/)
* A reference to a [run image](/docs/concepts/components/base-images/run/)

### Resources

Expand All @@ -29,4 +30,3 @@ To learn how to create your own builder, see our [Operator's Guide][operator-gui
[operator-guide]: /docs/operator-guide/
[buildpack]: /docs/concepts/components/buildpack/
[lifecycle]: /docs/concepts/components/lifecycle/
[stack]: /docs/concepts/components/stack/
50 changes: 13 additions & 37 deletions content/docs/concepts/components/stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ aliases=[

## What is a stack?

A stack is composed of two images that are intended to work together:
A stack (deprecated) is the grouping together of the build and run base images, represented by a unique ID.

1. The **build image** of a stack provides the base image from which the build environment is constructed. The build environment is the containerized environment in which the [lifecycle][lifecycle] (and thereby [buildpacks][buildpack]) are executed.
2. The **run image** of a stack provides the base image from which application images are built.
As of Platform API 0.12 and Buildpack API 0.10, stacks are deprecated in favor of existing constructs in the container image ecosystem such as operating system name, operating system distribution, and architecture.

For more information, see
* Platform API 0.12 [migration guide](/docs/reference/spec/migration/platform-api-0.11-0.12/)
* Buildpack API 0.10 [migration guide](/docs/reference/spec/migration/buildpack-api-0.9-0.10/)
* [Build image](/docs/concepts/components/base-images/build/) concept
* [Run image](/docs/concepts/components/base-images/run/) concept
* [Target data](/docs/concepts/components/targets/)

For older API versions, see below on using stacks.

<!--more-->

## Using stacks

> If you're using the `pack` CLI, running `pack stack suggest` will display a list of recommended
stacks that can be used when running `pack builder create`, along with each stack's associated build and run images.

## Using stacks

Stacks are used by [builders][builder] and are configured through a builder's
[configuration file](/docs/reference/config/builder-config/):

Expand All @@ -40,38 +48,6 @@ Stacks are used by [builders][builder] and are configured through a builder's
By providing the required `[stack]` section, a builder author can configure a stack's ID, build image, and run image
(including any mirrors).

### Run image mirrors

Run image mirrors provide alternate locations for run images, for use during `build` (or `rebase`).
When running `build` with a builder containing run image mirrors, `pack` will select a run image
whose registry location matches that of the specified app image (if no registry host is specified in the image name,
DockerHub is assumed). This is useful when publishing the resulting app image (via the `--publish` flag or via
`docker push`), as the app's base image (i.e. run image) will be located on the same registry as the app image itself,
reducing the amount of data transfer required to push the app image.

In the following example, assuming a builder configured with the example TOML above, the selected run image will be
`registry.example.com/example/run`.

```bash
$ pack build registry.example.com/example/app
```

while naming the app without a registry specified, `example/app`, will cause `example/run` to be selected as the app's
run image.

```bash
$ pack build example/app
```

> For local development, it's often helpful to override the run image mirrors in a builder. For this, the
> `pack config run-image-mirrors` command can be used. This command does not modify the builder, and instead configures the
> user's local machine.
>
> To see what run images are configured for a builder, the
> `inspect-builder` command can be used. `inspect-builder` will output built-in and locally-configured run images for
> a given builder, among other useful information. The order of the run images in the output denotes the order in
> which they will be matched during `build`.
## Resources

To learn how to create your own stack, see our [Operator's Guide][operator-guide].
Expand Down
28 changes: 28 additions & 0 deletions content/docs/concepts/components/targets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
+++
title="Targets"
weight=4
+++

The concept of "targets" is used to identify compatibility between buildpacks and base images.

Target data includes:
* Operating system name (e.g., "linux")
* Architecture (e.g., "amd64", "arm64")
* Architecture variant
* Operating system distribution name (e.g., "ubuntu", "alpine")
* Operating system distribution version (e.g., "22.04", "3.18.3")

For Linux-based images, operating system distribution name and version should be the values in `/etc/os-release` (`$ID` and `$VERSION_ID`).
For Windows-based images, operating system distribution name is blank, and version should be the value of `os.version` in the image config (e.g., `10.0.14393.1066`).

Buildpacks may declare the targets they are compatible with in `buildpack.toml`.
This information will be used by `pack` (or other platforms) and the lifecycle to avoid running buildpacks on images they aren't designed to work with.

Additionally, during builds this information will be read by the lifecycle from the run image and exposed to buildpacks through `CNB_TARGET_` environment variables:
* `CNB_TARGET_OS`
* `CNB_TARGET_ARCH`
* `CNB_TARGET_ARCH_VARIANT`
* `CNB_TARGET_DISTRO_NAME`
* `CNB_TARGET_DISTRO_VERSION`

Buildpacks can use this information to modify their behavior depending on the target.
17 changes: 6 additions & 11 deletions content/docs/concepts/operations/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,11 @@ summary="Build is the process of executing one or more buildpacks against the ap

![build diagram](/docs/concepts/operations/build.svg)

{{< param "summary" >}} Each buildpack inspects the
source code and provides relevant dependencies. An image is then generated from the app's source code and these
dependencies.
{{< param "summary" >}} Each buildpack inspects the source code and provides relevant dependencies.
An image is then generated from the app's source code and these dependencies.

Buildpacks are compatible with one or more [stacks](/docs/concepts/components/stack). A stack designates a **build image**
and a **run image**. During the build process, a stack's build image becomes the environment in which buildpacks are
executed, and its run image becomes the base for the final app image. For more information on working with stacks, see
the [Working with stacks](/docs/concepts/components/stack) section.
During the build process, the [build image](/docs/concepts/components/base-images/build/) becomes the environment in which buildpacks are executed,
and the [run image](/docs/concepts/components/base-images/run/) becomes the base for the final app image.

Buildpacks can be bundled together with a specific stack's build image, resulting in a
[builder](/docs/concepts/components/builder) image (note the "er" ending). Builders provide the most
convenient way to distribute buildpacks for a given stack. For more information on working with builders, see the
[Working with builders using `builder create`](/docs/concepts/components/builder) section.
Buildpacks can be bundled together with a specific build image, resulting in a [builder](/docs/concepts/components/builder) image.
Builders provide a convenient way to distribute buildpacks.
8 changes: 4 additions & 4 deletions content/docs/concepts/operations/rebase.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
+++
title="Rebase"
weight=2
summary="Rebase allows app developers or operators to rapidly update an app image when its stack's run image has changed."
summary="Rebase allows app developers or operators to rapidly update an app image when its run image has changed."
aliases=[
"/docs/using-pack/update-app-rebase/"
]
Expand All @@ -19,9 +19,9 @@ layer metadata to reference the newer base image version.

### Example: Rebasing an app image

Consider an app image `my-app:my-tag` that was originally built using the default builder. That builder's stack has a
run image called `pack/run`. Running the following will update the base of `my-app:my-tag` with the latest version of
`pack/run`.
Consider an app image `my-app:my-tag` that was originally built using the default builder.
That builder has a reference to a run image called `pack/run`.
Running the following will update the base of `my-app:my-tag` with the latest version of `pack/run`.

```bash
$ pack rebase my-app:my-tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ You should see:
ERROR: failed to launch: path lookup: exec: "curl": executable file not found in $PATH
```

What happened: our builder uses run image `cnbs/sample-stack-run:alpine`, which does not have `curl` installed, so our
What happened: our builder uses run image `cnbs/sample-base-run:alpine`, which does not have `curl` installed, so our
process failed to launch.

Let's take a look at how the `samples/curl` extension fixes the error by switching the run image to another image...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ The extension generates a `run.Dockerfile` that switches the run image to refere

<!-- test:exec -->
```bash
cat $PWD/samples/stacks/alpine/run/curl.Dockerfile
cat $PWD/samples/base-images/alpine/run/curl.Dockerfile
```

This is a simple Dockerfile that creates a CNB run image from the `curl` base image by adding the required CNB user configuration and `io.buildpacks.stack.id` label.
This is a simple Dockerfile that creates a CNB run image from the `curl` base image by adding the required CNB user configuration and labels.

The Dockerfile could come from anywhere, but we include it in the `stacks` directory for convenience.
The Dockerfile could come from anywhere, but we include it in the `base-images` directory for convenience.

Build the run image:

<!-- test:exec -->
```bash
docker build \
--file $PWD/samples/stacks/alpine/run/curl.Dockerfile \
--file $PWD/samples/base-images/alpine/run/curl.Dockerfile \
--tag localhost:5000/run-image-curl .

docker push localhost:5000/run-image-curl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ cd <your preferred workspace directory>
pack version
```

The version should be at least `0.30.0`
The version should be at least `0.31.0`

### Update pack configuration

Expand Down
16 changes: 10 additions & 6 deletions content/docs/operator-guide/create-a-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,20 @@ uri = "docker://cnbs/sample-package:hello-universe"
id = "samples/hello-processes"
version = "0.0.1"

# Stack that will be used by the builder
# Base images used to create the builder
[build]
image = "cnbs/sample-base-build:jammy"
[run]
[[run.images]]
image = "cnbs/sample-base-run:jammy"

# Stack (deprecated) used to create the builder
[stack]
id = "io.buildpacks.samples.stacks.jammy"
# This image is used at runtime
run-image = "cnbs/sample-stack-run:jammy"
run-image = "cnbs/sample-base-run:jammy"
# This image is used at build-time
build-image = "cnbs/sample-stack-build:jammy"
build-image = "cnbs/sample-base-build:jammy"
```

### 2. Create builder
Expand Down Expand Up @@ -97,10 +104,7 @@ For additional sample builders and buildpacks, check out our [samples][samples]

You can also check out our reference of the builder config [here][builder-config].

If you would like to customize the stack used by your builder, check out our [Create a stack][create-a-stack] tutorial.

[build]: /docs/concepts/operations/build/
[builder]: /docs/concepts/components/builder/
[builder-config]: /docs/reference/builder-config/
[create-a-stack]: /docs/operator-guide/create-a-stack
[samples]: https://github.com/buildpacks/samples
Loading

0 comments on commit 8464a43

Please sign in to comment.