Now we’ll change the build step you created to install application dependencies. This will require updates to the build
script such that it performs the following steps:
By doing this, you’ll learn how to create arbitrary layers with your buildpack, and how to read the contents of the app in order to perform actions like downloading dependencies.
Let’s begin by changing the node-js-buildpack/bin/build
so that it creates a layer for NodeJS.
A Buildpack layer is represented by a directory inside the layers directory provided to our buildpack by the Buildpack execution environment. As defined by the buildpack specification, the layers directory is always passed to the build
script as the first positional parameter. To create a new layer directory representing the NodeJS runtime, change the build
script to look like the following. The variable CNB_LAYERS_DIR
is provided to the build script as defined by the buildpacks specification.
#!/usr/bin/env bash
set -eo pipefail
echo "---> NodeJS Buildpack"
node_js_layer="${CNB_LAYERS_DIR}"/node-js
mkdir -p "${node_js_layer}"
The node_js_layer
directory is a sub-directory of the directory provided as the first positional argument to the build script (the layers directory), and this is where we’ll store the NodeJS runtime.
Next, we’ll download the NodeJS runtime and install it into the layer directory. Add the following code to the end of the build
script:
echo "---> Downloading and extracting NodeJS"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
This code uses the wget
tool to download the NodeJS binaries from the given URL, and extracts it to the node_js_layer
directory. We use tar
to extract the NodeJS distribution into the node_js_layer
. During the extraction we remove the top level directory (i.e. --strip-components 1
). This means that we will end up with ${node_js_layer}/bin
and ${node_js_layer}/lib
. When starting the container the layers bin
will automatically be added to the runtime ${PATH}
.
The last step in creating a layer is writing a TOML file that contains metadata about the layer. The TOML file’s name must match the name of the layer (in this example it’s node-js.toml
). Without this file, the Buildpack lifecycle will ignore the layer directory. For the NodeJS layer, we need to ensure it is available in the launch image by setting the launch
key to true
. Add the following code to the build script:
echo -e '[types]\nlaunch = true' > "${CNB_LAYERS_DIR}/node-js.toml"
Now the Buildpack is ready to test.
Your complete node-js-buildpack/bin/build
script should look like this:
#!/usr/bin/env bash
set -eo pipefail
echo "---> NodeJS Buildpack"
# 1. CREATE THE LAYER DIRECTORY
node_js_layer="${CNB_LAYERS_DIR}"/node-js
mkdir -p "${node_js_layer}"
# 2. DOWNLOAD node-js
echo "---> Downloading and extracting NodeJS"
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
# 3. MAKE node-js AVAILABLE DURING LAUNCH
echo -e '[types]\nlaunch = true' > "${CNB_LAYERS_DIR}/node-js.toml"
Build your app again:
pack build test-node-js-app --path ./node-js-sample-app --buildpack ./node-js-buildpack
You will see the following output:
===> DETECTING
...
===> RESTORING
===> BUILDING
[builder] ---> NodeJS Buildpack
[builder] ---> Downloading and extracting NodeJS
...
===> EXPORTING
...
Successfully built image 'test-node-js-app'
A new image named test-node-js-app
was created in your Docker daemon with a layer containing the NodeJS runtime. However, your app image is not yet runnable. We’ll make the app image runnable in the next section.