
Fundamentals of Docker containers
A form of container technology has existed in the Linux kernel since the 1970s. The technology powering today's containers, called cgroups, was introduced into the Linux kernel in 2006 by Google. The Docker company popularized the technology in 2013 by introducing an easy developer workflow. The company gave its name to the technology, so the name Docker can refer to both the company as well as the technology. Most commonly though, we use Docker to refer to the technology.
Docker as a technology is both a packaging format and a container runtime. We refer to packaging as an architecture that allows an application to be packaged together with its dependencies, such as binaries and runtime. The runtime points at the actual process of running the container images.
You can experiment with Docker by creating a free Docker account at Docker Hub (https://hub.docker.com/) and using that login to open Docker Labs (https://labs.play-with-docker.com/). This will give you access to an environment with Docker pre-installed that is valid for 4 hours. We will be using Docker Labs in this section as we build our own container and image.
Note
Although we are using the browser-based Docker Labs in this chapter to introduce Docker, you can also install Docker on your local desktop or server. For workstations, Docker has a product called Docker Desktop (https://www.docker.com/products/docker-desktop) that is available for Windows and Mac to create Docker containers locally. On servers – both Windows and Linux – Docker is also available as a runtime for containers.
Docker images
Docker uses an image to start a new container. An image contains all the software you need to run within your container. Container images can be stored locally on your machine, as well as in a container registry. There are public registries, such as the public Docker Hub (https://hub.docker.com/), or private registries, such as Azure Container Registry (ACR). When you, as a user, don't have an image locally on your PC, you will pull an image from a registry using the docker pull command.
In the following example, we will pull an image from the public Docker Hub repository and run the actual container. You can run this example in Docker Labs by following these instructions:
#First we will pull an image
docker pull docker/whalesay
#We can then look at which images we have locally
docker images
#Then we will run our container
docker run docker/whalesay cowsay boo
The output of these commands will look similar to Figure 1.1:

Figure 1.1: Example of running Docker in Docker Labs
What happened here is that Docker first pulled your image in multiple parts and stored it locally on the machine it was running on. When we ran the actual application, it used that local image to start a container. If we look at the commands in detail, you will see that docker pull took in a single parameter, docker/whalesay. If you don't provide a private container registry, Docker will look in the public Docker Hub for images, which is where Docker pulled our image from. The docker run command took in a couple of arguments. The first argument was docker/whalesay, which is the reference to the image. The next two arguments, cowsay boo, are commands that were passed to the running container to execute.
In the previous example, we learned that it is possible to run a container without building an image first. It is, however, very common that you will want to build your own images. To do this, you use a Dockerfile. A Dockerfile contains steps that Docker will follow to start from a base image and build your image. These instructions can range from adding files to installing software or setting up networking. An example of a Dockerfile is provided in the following code snippet, which we'll create in our Docker playground:
FROM docker/whalesay:latest
RUN apt-get -y -qq update && apt-get install -qq -y fortunes
CMD /usr/games/fortune -a | cowsay
There are three lines in this Dockerfile. The first one will instruct Docker which image to use as a source image for this new image. The next step is a command that is run to add new functionality to our image. In this case, updating our apt repository and installing an application called fortunes. Finally, the CMD command tells Docker which command to execute when a container based on this image is run.
You typically save a Dockerfile in a file called Dockerfile, without an extension. To build our image, you need to execute the docker build command and point it to the Dockerfile you created. In building the Docker image, the process will read the Dockerfile and execute the different steps in the Dockerfile. This command will also output the steps it took to run a container and build your image. Let's walk through a demo of building our own image.
In order to create this Dockerfile, open up a text editor via the vi Dockerfile command. vi is an advanced text editor in the Linux command line. If you are not familiar with it, let's walk through how you would enter the text in there:
- After you've opened vi, hit the i key to enter insert mode.
- Then, either copy-paste or type the three code lines.
- Afterward, hit the Esc key, and type :wq! to write (w) your file and quit (q) the text editor.
The next step is to execute docker build to build our image. We will add a final bit to that command, namely adding a tag to our image so we can call it by a useful name. To build your image, you will use the docker build -t smartwhale . command (don't forget to add the final dot here).
You will now see Docker execute a number of steps – three in our case – in order to build our image. After your image is built, you can run your application. To run your container, you would run docker run smartwhale, and you should see an output similar to Figure 1.2. However, you will probably see a different smart quote. This is due to the fortunes application generating different quotes. If you run the container multiple times, you will see different quotes appear, as shown in Figure 1.2:

Figure 1.2: Example of running a custom container
That concludes our overview and demo of Docker. In this section, you started with an existing container image and launched that on Docker Labs. Afterward, you took that a step further and built your own container image and started containers using your own image. You have now learned what it takes to build and run a container. In the next section, we will cover Kubernetes. Kubernetes allows you to run multiple containers at scale.