Creating the Base Image
The first step is to establish the base image used during the build stage. This image is crucial as it defines the environment for processing buildpacks and ultimately creating the final runtime image.Dockerfile: build-base.Dockerfile
Create a Dockerfile named build-base.Dockerfile with the following content. This file uses Ubuntu Jammy as the base image, installs required utilities (including xz-utils, ca-certificates, jq, wget, and curl), and adds the YJ tool. It also configures the CNB user and group information.To further enhance your base image, add commands to create a dedicated user and group for CNB and label your distribution.
Enhancing the Dockerfile
Append the following commands to the Dockerfile to create a user, assign group privileges, and add metadata labels:Building the Base Image
Execute the following command to build the base image:Creating the Runtime Image
Next, we will create the runtime image, which will host your application and include only the essential runtime dependencies.Dockerfile: run-base.dockerfile
Create a file named run-base.dockerfile with the following content. The runtime Dockerfile is similar to the build image but installs fewer packages.Building the Runtime Image
Run the following command to build the runtime image:Configuring the Builder with builder.toml
With both the build and runtime images in place, the next step is to configure your builder using a builder.toml file. This configuration file specifies the buildpacks to include and outlines the order in which they will execute during the detection phase.Defining Buildpacks and Order
Create the builder.toml file in your builder directory with the following contents. In this example, we include a JavaScript buildpack and a sample buildpack:Specifying Base Images
Complete your builder.toml configuration by specifying the base images for both the build and run phases:Creating and Testing the Builder
After configuring your builder, use the Pack CLI to create your builder image. Run the following command:docker image ls), you can test it by building a sample image from your Node.js application. Change to the directory containing your application and execute:
Build Process Overview
During the build process, you will see several distinct phases:- ANALYZING – Checks for an existing image.
- DETECTING – Runs the detection phase for your buildpacks (e.g., my-js-buildpack, samples/hello-world, and samples/hello-moon).
- RESTORING and BUILDING – Installs Node.js (for example, version 18.18.1) along with its dependencies, caches layers, and finalizes the image.
Ensure that the builder image is correctly created before attempting to build your application, as this step validates your configuration and buildpack order.
Summary
In this lesson, you have learned how to create a custom builder for buildpacks by:- Defining a base image (build-base) and a runtime image (run-base) using dedicated Dockerfiles.
- Configuring a builder.toml file to list the required buildpacks and specify the detection order.
- Creating and testing the builder using the Pack CLI to build a sample Node.js application image.