Skip to content

Commit 114efac

Browse files
committed
Further simplify create-buildpack example
Use a "fake" server application. Cache the runtime for use in subsequent builds. Signed-off-by: Aidan Delaney <[email protected]>
1 parent ce1f1eb commit 114efac

File tree

9 files changed

+137
-310
lines changed

9 files changed

+137
-310
lines changed

content/docs/buildpack-author-guide/create-buildpack/adding-bill-of-materials.md

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ cat >> "${layersdir}/node-js.sbom.cdx.json" << EOL
7878
{
7979
"type": "library",
8080
"name": "node-js",
81-
"version": "$node-js_version"
81+
"version": "${node_js_version}"
8282
}
8383
]
8484
}
@@ -88,7 +88,7 @@ EOL
8888
We can also add an SBOM entry for each dependency listed in `package.json`. Here we use `jq` to add a new record to the `components` array in `bundler.sbom.cdx.json`:
8989

9090
```bash
91-
cnode-jsbom="${layersdir}/node-js.sbom.cdx.json"
91+
node-jsbom="${layersdir}/node-js.sbom.cdx.json"
9292
cat >> ${node-jsbom} << EOL
9393
{
9494
"bomFormat": "CycloneDX",
@@ -98,22 +98,11 @@ cat >> ${node-jsbom} << EOL
9898
{
9999
"type": "library",
100100
"name": "node-js",
101-
"version": "$node-js_version"
101+
"version": "${node_js_version}"
102102
}
103103
]
104104
}
105105
EOL
106-
if [[ -f package.json ]] ; then
107-
for gem in $(gem dep -q | grep ^Gem | sed 's/^Gem //')
108-
do
109-
version=${gem##*-}
110-
name=${gem%-${version}}
111-
DEP=$(jq --arg name "${name}" --arg version "${version}" \
112-
'.components[.components| length] |= . + {"type": "library", "name": $name, "version": $version}' \
113-
"${node-jsbom}")
114-
echo ${DEP} > "${node-jsbom}"
115-
done
116-
fi
117106
```
118107

119108
Your `node-js-buildpack/bin/build`<!--+"{{open}}"+--> script should look like the following:
@@ -125,38 +114,46 @@ set -eo pipefail
125114

126115
echo "---> NodeJS Buildpack"
127116

117+
# ======= MODIFIED =======
128118
# 1. GET ARGS
129119
layersdir=$1
130120
plan=$3
131121

132122
# 2. CREATE THE LAYER DIRECTORY
133-
node-js_layer="${layersdir}"/node-js
134-
mkdir -p "${node-js_layer}"
123+
node_js_layer="${layersdir}"/node-js
124+
mkdir -p "${node_js_layer}"
135125

126+
# ======= MODIFIED =======
136127
# 3. DOWNLOAD node-js
137-
node-js_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "node-js") | .metadata.version')
138-
echo "---> Downloading and extracting NodeJS"
139-
node-js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
140-
wget -q -O - "$node-js_url" | tar -xxf - -C "${node-js_layer}"
141-
142-
# 4. MAKE node-js AVAILABLE DURING LAUNCH
143-
echo -e '[types]\nlaunch = true' > "${layersdir}/node-js.toml"
128+
node_js_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "node-js") | .metadata.version') || "18.18.1"
129+
node_js_url=https://nodejs.org/dist/v18.18.1/node-v${node_js_version}-linux-x64.tar.xz
130+
remote_nodejs_version=$(cat "${layersdir}/node-js.toml" 2> /dev/null | yj -t | jq -r .metadata.nodejs-version 2>/dev/null || echo 'NOT FOUND')
131+
if [[ "${node_js_url}" != *"${remote_nodejs_version}"* ]] ; then
132+
echo "-----> Downloading and extracting NodeJS"
133+
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
134+
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
135+
cat >> "${layersdir}/node-js.toml" << EOL
136+
[metadata]
137+
nodejs-version = "${node_js_version}"
138+
EOL
139+
else
140+
echo "-----> Reusing NodeJS"
141+
fi
144142

145-
# 5. MAKE node-js AVAILABLE TO THIS SCRIPT
146-
export PATH="${node-js_layer}"/bin:$PATH
147-
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"${node-js_layer}/lib"
143+
# 4. MAKE node-js AVAILABLE DURING LAUNCH and CACHE the LAYER
144+
echo -e '[types]\ncache = true\nlaunch = true' > "${layersdir}/node-js.toml"
148145

149-
# 6. SET DEFAULT START COMMAND
146+
# ========== ADDED ===========
147+
# 5. SET DEFAULT START COMMAND
150148
cat > "${layersdir}/launch.toml" << EOL
151-
# our web process
152149
[[processes]]
153150
type = "web"
154151
command = "node app.js"
155152
default = true
156153
EOL
157154

158155
# ========== ADDED ===========
159-
# 7. ADD A SBOM
156+
# 6. ADD A SBOM
160157
node-jsbom="${layersdir}/node-js.sbom.cdx.json"
161158
cat >> ${node-jsbom} << EOL
162159
{
@@ -167,7 +164,7 @@ cat >> ${node-jsbom} << EOL
167164
{
168165
"type": "library",
169166
"name": "node-js",
170-
"version": "$node-js_version"
167+
"version": "${node_js_version}"
171168
}
172169
]
173170
}
@@ -197,7 +194,7 @@ The SBOM information is now downloaded to the local file system:
197194
cat layers/sbom/launch/examples_node-js/node-js/sbom.cdx.json | jq -M
198195
```
199196

200-
You should find that the included `node-js` version is `3.1.0` as expected.
197+
You should find that the included `node-js` version is `18.18.1` as expected.
201198

202199
<!-- test:assert=contains;ignore-lines=... -->
203200
```text
@@ -209,7 +206,7 @@ You should find that the included `node-js` version is `3.1.0` as expected.
209206
{
210207
"type": "library",
211208
"name": "node-js",
212-
"version": "3.1.0"
209+
"version": "18.18.1"
213210
},
214211
...
215212
]

content/docs/buildpack-author-guide/create-buildpack/build-app.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ Next, we'll download the NodeJS runtime and install it into the layer directory.
3939
```bash
4040
echo "---> Downloading and extracting NodeJS"
4141
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
42-
wget -q -O - "${node_js_url}" | tar -xJf - -C "${node_js_layer}"
42+
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
4343
```
4444

45-
This code uses the `wget` tool to download the NodeJS binaries from the given URL, and extracts it to the `node_js_layer` directory.
45+
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}`.
4646

4747
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:
4848

@@ -74,14 +74,10 @@ mkdir -p "${node_js_layer}"
7474
# 3. DOWNLOAD node-js
7575
echo "---> Downloading and extracting NodeJS"
7676
node_js_url=https://nodejs.org/dist/v18.18.1/node-v18.18.1-linux-x64.tar.xz
77-
wget -q -O - "${node_js_url}" | tar -xJf - -C "${node_js_layer}"
77+
wget -q -O - "${node_js_url}" | tar -xJf - --strip-components 1 -C "${node_js_layer}"
7878

7979
# 4. MAKE node-js AVAILABLE DURING LAUNCH
8080
echo -e '[types]\nlaunch = true' > "${layersdir}/node-js.toml"
81-
82-
# 5. MAKE node-js AVAILABLE TO THIS SCRIPT
83-
export PATH="${node_js_layer}"/bin:$PATH
84-
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"${node_js_layer}/lib"
8581
```
8682

8783
Build your app again:

0 commit comments

Comments
 (0)