Docker is a helpful tool that allows you to recreate an environment very quickly. It can replace many use cases that were previously solved using virtual machines & Docker does it better, requiring less resources and being able to process instructions natively at full speed.

Many of the available tutorials introduce Docker by building and running an existing image for a particular application. I found this frustrating as someone who was capable of, and wanted to, create their own image. For this reason, this tutorial will introduce Docker from the perspective of writing Dockerfiles.

Docker overview

The diagram above shows a schematic for how the process works. The base image is downloaded, usually from the internet. The rectangle on the left shows the steps written in the Dockerfile.

  1. Specify which base image you want
    • this can be a plain OS like Ubuntu or an application like gitlab.
  2. The various instructions to setup your container
    • like installing software or copying files onto the container
  3. The command to run when the container is run
    • for example, starting a Jupyter notebook server

Building the Dockerfile creates an image, which contains all the software and files for the operating system and your environment to run. This can then be used to create containers, which is an OS launched from the image.

Installation on Ubuntu 16.04 and 16.10

The command below installs the docker package and its dependencies.

sudo apt install docker.io

Adding your user to the docker group

Docker commands can only be run by the root user and users in the docker group. As you don’t want to have to be running all of your docker commands as root, you can add yourself to the group by executing the command below and logging out and back in.

sudo usermod -a -G docker $USER

Creating a simple Dockerfile

The Dockerfile describes a set of commands that are executed in order to create a docker image (which can then be used to create docker containers). A very simple Dockerfile example is shown below.

from ubuntu:16.04
RUN apt-get -y update && apt-get install -y htop
CMD htop
  • The first line selects the 16.04 image from the Ubuntu DockerHub account as the base image
  • The second line installs htop
  • The third line (CMD) specifies the command that should be run on boot

Building and running

First we need to build a Docker image from the Dockerfile we created above. We do this by running the below command in the same directory as the Dockerfile. The -t flag indicates we want to specify the name of the image.

docker build -t <imagename> .

And now to run a container run the following command:

docker run -ti <imagename>

If you haven’t seen htop before, it is an ncurses program that shows resource usage of a system as well as the top resource using processes. Once the Docker container starts it will show something similar to below.

You can quit using q or Ctrl-C

The resources shown are quite instructive of what is happening when you run the docker container. The Docker container has full access to the resources of my system (4 core CPU and 32 GB RAM), but cannot see any of the other processes running on my machine. This is different to VMs, where there would be a certain amount of resources allocated to the VM.

Looking around in the container

If you have been following along, you will notice that using Docker run immediately runs htop, and when you quit htop, it closes the container as well. In order to get in to the container to examine the directory structure, you don’t need to use SSH. The CMD line in our Dockerfile can be overridden by supplying the command as the final argument of docker run, as below.

docker run -ti <imagename> /bin/bash

If we have a look around in here, we can see that the files from the host computer are not accessible from within the container (e.g. try running ls /home/).

Getting help

The built in help system for Docker is very good. You can access it with docker --help, which lists the available top level commands. You can then call help on one of those commands, if we take run as an example, running docker run --help returns a help page specifically for that command.