Platforms can have several run images available, each tailored to a specific language family - thus limiting the number of installed dependencies for each image to the minimum necessary to support the targeted language. Image extensions can be used to switch the run image to that most appropriate for the current application.
curl
extensioncat $PWD/samples/extensions/curl/bin/detect
The extension always detects (because its exit code is 0
) and provides a dependency called curl
.
cat $PWD/samples/extensions/curl/bin/generate
The extension generates a run.Dockerfile
that switches the run image to reference localhost:5000/run-image-curl
.
curl
extension to usecat $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 labels.
The Dockerfile could come from anywhere, but we include it in the base-images
directory for convenience.
Build the run image:
docker build \
--file $PWD/samples/base-images/alpine/run/curl.Dockerfile \
--tag localhost:5000/run-image-curl .
docker push localhost:5000/run-image-curl
hello-extensions
buildpack to require curl
Set the BP_REQUIRES
build-time environment variable to configure the hello-extensions
buildpack to require both vim
and curl
(review the ./bin/detect
script to see why this works).
pack build hello-extensions \
--builder localhost:5000/extensions-builder \
--env BP_EXT_DEMO=1 \
--env BP_REQUIRES=vim,curl \
--path $PWD/samples/apps/java-maven \
--pull-policy always \
--network host \
--verbose
Note that --network host
is necessary when publishing to a local registry.
You should see:
[detector] ======== Results ========
[detector] pass: samples/vim@0.0.1
[detector] pass: samples/curl@0.0.1
[detector] pass: samples/cowsay@0.0.1
[detector] pass: samples/hello-extensions@0.0.1
[detector] Resolving plan... (try #1)
[detector] skip: samples/cowsay@0.0.1 provides unused cowsay
[detector] 3 of 4 buildpacks participating
[detector] samples/vim 0.0.1
[detector] samples/curl 0.0.1
[detector] samples/hello-extensions 0.0.1
[detector] Running generate for extension samples/vim@0.0.1
...
[detector] Running generate for extension samples/curl@0.0.1
...
[detector] Checking for new run image
[detector] Found a run.Dockerfile from extension 'samples/curl' setting run image to 'localhost:5000/run-image-curl'
...
[extender (build)] Found build Dockerfile for extension 'samples/vim'
[extender (build)] Applying the Dockerfile at /layers/generated/build/samples_vim/Dockerfile...
...
[extender (build)] Running build command
[extender (build)] ---> Hello Extensions Buildpack
[extender (build)] VIM - Vi IMproved 9.0 (2022 Jun 28, compiled May 19 2023 16:28:36)
...
Successfully built image hello-extensions
docker run --rm hello-extensions
You should see something akin to:
curl 7.85.0-DEV (x86_64-pc-linux-musl) ... more stuff here ...
What happened: now that hello-extensions
requires both vim
and curl
in its build plan, both extensions are
included in the build and provide the needed dependencies for build and launch, respectively
vim
extension installs vim
at build time, as beforecurl
extension switches the run image to localhost:5000/run-image-curl
, which has curl
installedNow our curl
process can succeed!
Our curl
process succeeded, but there is another process type defined on our image:
docker run --rm --entrypoint cowsay hello-extensions
You should see:
ERROR: failed to launch: path lookup: exec: "cowsay": executable file not found in $PATH
Our run image, localhost:5000/run-image-curl
, has curl
installed, but it doesn’t have cowsay
.
In general, we may not always have a preconfigured run image available with all the needed dependencies for the current application. Luckily, we can also use image extensions to dynamically install runtime dependencies at build time. Let’s look at that next.