Containerize an application
In the following guide you will try and deploy a simple Node.js webapp, based on Docker’s get-started guide. This guide does not go into details of the webapp, so no prior knowledge of Node.js or JavaScript is required.
Pre-requisites
- A conceptual understanding of containers and images.
- Kleened and Klee installed and configured on the host so they can communicate with each other.
git
Get the app
Before you can run the application, you need to get the application source code onto your machine.
-
Clone the getting-started repository using the following command:
$ git clone https://github.com/docker/getting-started.git -
View the contents of the cloned repository. Inside the
approot-directory of the repository you should see apackage.json, two subdirectories (srcandspec), and perhaps a few other files.
Prepare the Kleened host
When you have a fresh installation, a few preparations is needed before you can start building images and creating containers.
You need to create a base image and a network to use for the images and containers that are created in this guide.
-
Create a base image. The simplest way to do this is to let Kleened find and download an approriate relase of the FreeBSD userland:
$ klee image create fetch-auto -
Optional: In order for you to isolate your containers from the host networking create a dedicated network to use for our containers:
$ klee network create --subnet 10.13.37.0/24 testnetIt is recommended to connect containers to a network, instead of using the default
hostnetwork driver for connectivty. Using networks provides a higher degree of isolation from the host’s networking configuration. If you decide to use thehostnetwork driver instead, remember to omit the-n testnetoption when creating containers in this guide.
Build the app’s container image
In order to build the container image, you’ll need to use a Dockerfile.
A Dockerfile contains the instructions that Kleened uses to create the image.
-
In the
appdirectory mentioned previously, create a file namedDockerfile.You can use the following commands below to create a Dockerfile, replacing
/path/to/with the path to yourgetting-startedrepository.$ cd /path/to/app $ touch Dockerfile -
Add the following contents to the Dockerfile:
FROM FreeBSD-13.2-RELEASE:latest RUN pkg install -y node20 npm-node20 yarn-node20 WORKDIR /app COPY . . RUN yarn install --production # Listens on port 3000 CMD cd /app && node src/index.jsNote
Click on an instruction in the Dockerfile example to learn more about the instruction.
-
Build the container image, and assuming you are still in the
appdirectory, run$ klee build -t webapp .to build the container image.
Kleene uses the Dockerfile to build a new container image.
The Dockerfile starts with FROM FreeBSD-13.2-RELEASE:latest that refers to the base-image we created previously,
so it will be used as the foundation for our new webapp image.
The remaining instructions from the Dockerfile installs the application dependencies, copies application data into the image, and uses yarn to install the application’s JavaScript dependencies.
The CMD directive specifies the default command to run when starting a container from this image, which in this case is set to run the application.
Finally, the -t flag tags your image. Think of this simply as a human-readable name for the final image. Since you named the image webapp,
you can refer to that image when you run a container. Since we have not specified a tag, Kleene tags the image with latest.
The . at the end of the klee build command tells Kleene that it should look for the Dockerfile in the current directory.
Note
The directory
.is converted to its absolute path by Klee and then sent to Kleened. Kleened will then interpret this as a path on the host machine where it is running. If Klee and Kleened are runnning on the same host this is fine, but if Klee is running on a remote machine this will probably not work. In the latter case, remember to use absolute paths on the host machine where Kleened is running.
Start an app container
Now that you have an image, you can run the application in a container.
To do so, you will use the klee run command.
-
Start your container and specify the name of the image you just created:
$ klee run -n testnet -d webappUsing
-n testnetconnects the new container to our recently createdtestnetnetwork, providing connectivity for thewebappcontainer. The new container runs in “detached” mode (in the background) when the-dflag is used. - Verify that the container is running as expected using
klee lsc. This command shows the id and auto-generated name of your new container. It is also possible to verify that the container is running using the FreeBSD native tooljls:$ jls JID IP Address Hostname Path 6 10.13.37.1 /zroot/kleene/container/d23e37375ffdThis also shows the ip address of the container that is needed for accessing the web application. Note that the IP is shown because the container uses the
ipnetnetwork driver. -
After a few seconds, open your web browser to http://10.13.37.1:3000. If you are not running the container locally you might need to access the app at another location or use a port forward etc. For example, using portforward with
sshsuch asssh -L 3000:10.13.37.1:3000 ...you should be able to access the web application on http://localhost:3000 instead.
- Go ahead and add an item or two and see that it works as you expect. You can mark items as complete and remove items. Your frontend is successfully storing items in the backend.
At this point, you should have a running todo list manager with a few items, all built by you.
Note that our images and containers are just zfs datasets one the host. Use zfs list to get an overview of how Kleene
stores its objects.
Next steps
Next, you’re going to make a modification to your app and learn how to update your running application with a new image. Along the way, you’ll learn a few other useful commands.