Example – Node.js/Express container image

This example follows the same pattern as the Python example, a simple Node.js application built with the Express library to walk through the details of how to use Kubernetes. If you are more familiar with JavaScript development, this example may be more meaningful. The sample application is directly from the Express documentation (https://expressjs.com/en/starter/generator.html).

You can get a download a copy of this code from GitHub at https://github.com/kubernetes-for-developers/kfd-nodejs/tree/first_container. Since we will evolve these files, the code referenced here is available at the first_container tag. If you want to use Git to retrieve these files, you can do so using the following commands:

git clone https://github.com/kubernetes-for-developers/kfd-nodejs
cd kfd-nodejs
git checkout tags/first_container

Like the Python example, we will start with the Dockerfile. As a reminder, this is what defines what gets built into a container, and how it happens. The goals of this Dockerfile are:

  • Get and install any critical security patches for the underlying operating system
  • Install the language or runtime that we'll need to use to run our code
  • Install any dependencies for our code that aren't included directly in our source control
  • Copy our code into the container
  • Define how and what to run
FROM alpine
# load any public updates from Alpine packages
RUN apk update
# upgrade any existing packages that have been updated
RUN apk upgrade
# add/install python3 and related libraries
# https://pkgs.alpinelinux.org/package/edge/main/x86/python3
RUN apk add nodejs nodejs-npm
# make a directory for our application
WORKDIR /src
# move requirements file into the container
COPY package.json .
COPY package-lock.json .
# install the library dependencies for this application
RUN npm install --production
# copy in the rest of our local source
COPY . .
# set the debug environment variable
ENV DEBUG=kfd-nodejs:*
CMD ["npm", "start"]

Like the Python example, this container is based on Alpine Linux. You will see several commands that may not be familiar, specifically the apk command. As a reminder, this command is used to install, update, and remove Alpine Linux packages. These commands update the Alpine package repository, upgrade all installed and pre-existing packages in the image, and then install nodejs and npm from packages. Those steps basically bring us to a minimal container that can run a Node.js application.

The next commands make a directory in the container at /src to house our source code, copy in the package.json file, and then use npm to install the dependencies for running the code. The --production option used with the npm install command installs only those items listed in package.json that are needed for running the code - development dependencies are excluded. Node.js makes it easy and consistent to maintain your dependencies with its package.json format, and it is good practice to separate out dependencies needed in production from those needed in development.

The last two commands leverage ENV and CMD. This differs from the Python example where I used CMD and ENTRYPOINT to highlight how they work together. In this example, I use the ENV command to set the DEBUG environment variable to match the example instructions in the Express documentation. CMD then contains a command to start our code, which simply leverages npm to run the command defined in package.json, and uses the earlier WORKDIR command to set the local directory for that invocation.