Skip to main content
In this lesson, you will learn how to use the Pack CLI to create a container image from your source code. We will use a simple Node.js web application as an example to demonstrate the process.

Overview of the Node.js Application

The main application file, index.js, starts a web server using Express. Below is the complete code:
In addition to the application code, the project includes a package.json file that specifies the third-party dependencies required by the application (such as Express and UUID). When installed, these dependencies appear in the node_modules folder alongside your application code.
The node_modules folder contains the application dependencies for Express and UUID, ensuring that your app runs correctly.

Building the Container Image

Before building the image, you need a builder. If your organization provides one, you can reference that; otherwise, you can use the Pack CLI command to get suggestions for pre-built default builders:
This command displays several builder options. For example, the output might look like:
Each builder is distributed as a Docker image. In this demonstration, we will use the Google builder (gcr.io/buildpacks/builder:google-22) as it is the first option on the list.

Creating the Container Image

Use the Pack CLI to create your container image. Here, we name the image “myapp”, specify the path to your Node.js application source code, and choose the builder:
When you run this command, the CLI provides real-time output that explains each stage of the build process. Initially, it pulls the builder image:
After downloading the builder image, the build process advances through several stages:
  1. Detection:
    Each buildpack inspects the source code to decide whether it should execute. For the Node.js application, buildpacks check for files like package.json or package-lock.json. In this example, three out of five buildpacks detected that they needed to run.
  2. Restoration:
    Previous build metadata is restored. Although this step is useful for caching and speeding up subsequent builds, it is not the primary focus here.
  3. Building:
    During this stage, the builder installs Node.js (if it isn’t cached already) and executes npm install to populate the node_modules folder with your application’s dependencies. Here is an excerpt from the build log:
  1. Exporting:
    The final stage involves assembling the image layers. The default process type is set to “web,” which will serve as the container’s startup command.
You can verify that the image was built successfully by running:

Testing the Container Image

After the image is built, you can test it by creating and running a container. Since the application listens on port 8080, map it to port 8000 on your host machine:
To verify that the container is running, check the container list with:
Finally, use an HTTP request to interact with the application:
The expected output is:
This confirms that the application image has been built correctly and the container is operational.

Exploring Pack CLI Commands

For additional commands and options, you can run:
This command displays options for working with builders, buildpacks, stacks, extensions, and more. One particularly useful command is pack inspect, which provides detailed information about the image built by the buildpacks. For example:
The output will include details such as the base image, applied buildpacks, and defined processes:
This output indicates that three buildpacks were applied: Node.js Runtime, Node.js NPM, and Google’s Util Label-Image. The defined process, “web,” sets the command node index.js within the /workspace directory.
Although some code blocks (such as the Node.js application code) appear multiple times in the process, they are presented only once in full to avoid redundancy.

Publishing the Container Image

Finally, learn how to publish the built image to a container registry (e.g., Docker Hub). Ensure you log in first:
After logging in, build and publish the image with the appropriate naming convention and the publish flag:
If everything is set up correctly, you will see output similar to the following as the image is published:
Visit your Docker Hub repository to verify that the image has been successfully pushed.

Conclusion

This lesson has demonstrated how to use the Pack CLI to create, inspect, run, and publish a cloud-native application image built from source code. With these techniques, you can experiment with buildpacks to containerize your applications efficiently. For further reading, check out the following resources: Explore additional guides on Kubernetes Documentation and Docker Hub for more containerization practices. Happy building and containerizing!

Watch Video