Introduction

Docker is an application that virtualize the operating system so that many container-based applications can run on top of a single OS instance. Unlike virtual machines which requires a complete guest OS to be installed, Docker replaces the guest OS layer with a much smaller resources footprint. This allows greater portability, uses less resources which results in better robustness. For more information, check out the official Docker website.

In this tutorial, you'll learn how to install Docker and use it on an existing Ubuntu 16.04 instance.

Prerequisites

To follow this tutorial, you will need the following:

  • 64-bit Ubuntu 16.04 server with non-root user

Note: Docker requires the 64-bit version of Ubuntu with a kernel version equal to or greater than 3.10. The default 64-bit Ubuntu 16.04 server meets these requirements.

Commands in this tutorial should be run as a non-root user. If root execution is required for the command, it should be prefixed with sudo.

Step 1 — Installing Docker

While the Ubuntu package repositories has Docker, usually it is not the latest version. To get the most up-to-date version, we need to use the Docker repository. In this step, we will install the latest Docker version.

Ubuntu ensures the authenticity of software packages by verifying that they are signed with GPG keys. Therefore, we need to import the key for the official Docker repository.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Let's add the Docker repository to APT sources:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Next, update the Ubuntu package database with the Docker packages from the newly added repo:

sudo apt update

Make sure you are about to install from the Docker repo instead of the default Ubuntu 16.04 repo:

apt-cache policy docker-ce

You should see output similar to the follow:

[label Output of apt-cache policy docker-ce]
docker-ce:
  Installed: (none)
  Candidate: 17.06.2~ce-0~ubuntu
  Version table:
     17.06.2~ce-0~ubuntu 500
        500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
     17.06.1~ce-0~ubuntu 500
        500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
     . . .

Notice that docker-ce is not installed, but the candidate for installation is from the Docker repository for Ubuntu 16.04. The docker-ce version number might be different.

Next, we will install Docker:

sudo apt install -y docker-ce

Docker should now be installed, the daemon started, and the process enabled to start on boot. Check that it's running:

sudo systemctl status docker

The output should be similar to the following, showing that the service is active and running:

[secondary_label Output]
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-09-14 14:59:43 MYT; 14s ago
     Docs: https://docs.docker.com
 Main PID: 3238 (dockerd)
 . . .

This Docker installation includes the Docker service (daemon) and the Docker client.

Step 2 — Executing the Docker Command Without Sudo

By default, running the docker command requires root privileges which means you have to prefix the command with sudo. Alternatively, Docker can be run by a user in the docker group, which is created automatically during the Docker installation. If you attempt to run the docker command without prefixing it with sudo or your user is not in the docker group, you will get a similar output as follows:

[secondary_label Output]
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.
. . .

To avoid typing sudo whenever you run the docker command, please add your username to the docker group:

sudo usermod -aG docker ${USER}

To apply the new group membership, you can log out of the server and back in, or you can type the following:

su - ${USER}

You will be prompted to enter your user's password to continue. Once you have logged in, you can confirm that your user is added to the docker group by typing:

id -nG
[secondary_label Output]
<^>yourusername<^> ... docker

If you need to add a user to the docker group that you're not logged in as, declare that username explicitly using:

sudo usermod -aG docker username

The rest of this article assumes you are running the docker command as a user in the docker user group. If you choose not to, remember to prefix the commands with sudo.

Step 3 — Using the Docker Command

Now that Docker is installed and working, let's get familiar with the Docker client. Using docker consists of passing it a chain of options and commands followed by arguments. The syntax takes this form:

docker [option] [command] [arguments]

To view all available subcommands, type:

docker

A few subcommands are shown below:

[secondary_label Output]

    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders between a container and the local filesystem
    create    Create a new container
    . . .

To view the switches available to a specific command, type:

docker docker-subcommand --help

To view system-wide information about Docker, use:

docker info

Step 4 — Working with Docker Images

We use Docker images from the Docker Hub registry to run containers and applications. Anyone can build and host Docker images on Docker Hub. Therefore, most applications and Linux distributions you will need to run Docker containers have images that are hosted on Docker Hub.

To check whether you can access and download images from Docker Hub, type:

docker run hello-world

An output similar to the following shows that Docker is working correctly:

[secondary_label Output]
. . .
Hello from Docker.
This message shows that your installation appears to be working correctly.
...

You can search for images available on Docker Hub by using the docker command with the search subcommand. For example, to search for the Ubuntu image, type:

docker search ubuntu

This command will access Docker Hub and return a list of available images matching the search string. In this example, the output will be similar to this:

[secondary_label Output]
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                            Ubuntu is a Debian-based Linux operating s...   3808      [OK]       
ubuntu-upstart                    Upstart is an event-based replacement for ...   61        [OK]       
torusware/speedus-ubuntu          Always updated official Ubuntu docker imag...   25                   [OK]
rastasheep/ubuntu-sshd            Dockerized SSH service, built on top of of...   24                   [OK]
ubuntu-debootstrap                debootstrap --variant=minbase --components...   23        [OK]       
nickistre/ubuntu-lamp             LAMP server on Ubuntu                           6                    [OK]
nickistre/ubuntu-lamp-wordpress   LAMP on Ubuntu with wp-cli installed            5                    [OK]
nuagebec/ubuntu                   Simple always updated Ubuntu docker images...   4                    [OK]
nimmis/ubuntu                     This is a docker images different LTS vers...   4                    [OK]
maxexcloo/ubuntu                  Docker base image built on Ubuntu with Sup...   2                    [OK]
admiringworm/ubuntu               Base ubuntu images based on the official u...   1                    [OK]

...

Under the OFFICIAL column, OK indicates an image built and supported by the company behind the Docker project. Once you have identified the image which you would like to use, you can download it to your computer using the pull subcommand:

docker pull ubuntu

Once the image has been downloaded, you may then run a container using the downloaded image with the run subcommand. If an image has not been downloaded yet when docker is executed with the run subcommand, then the Docker client will proceed to download the image first and then run a container using it:

docker run ubuntu

To display the images that have been downloaded to your computer, execute:

docker images

The output should look like the following:

[secondary_label Output]
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              8b72bba4485f        27 hours ago          120 MB
hello-world         latest              05a3bd381fc2        33 hours ago         1.84kB

In the next step, we want to try running a Docker container.

Step 5 — Running a Docker Container

The previous hello-world container which you ran is an example of a container that runs and exits, after emitting a test message. Containers are much more useful than that and you can run applications on them.

For example, let's run a container using the latest image of Ubuntu. The combination of the -i and -t switches allows interactive shell access in the container:

docker run -it ubuntu

Your command prompt should change to reflect the fact that you are now working inside the container and should take a similar form like this:

[secondary_label Output]
root@669d7e624344:/#

Important: Note the container id in the command prompt. In the above example, it is 669d7e624344.

From this terminal, you can run any command inside the container. For example, let's update the package database inside the container. You do not need to prefix any command with sudo, because you are operating with root privileges:

apt update

Then install any application in it. For example, you can install NodeJS:

apt install -y nodejs

Step 6 — Committing Changes in a Container to a Docker Image

When running a Docker image, you can create, modify, and delete files just as when you run an operating system or a virtual machine. However, the changes which you make will only apply to that container. You can start and stop it, but once you destroy it with the docker rm command, the changes will be lost permanently.

This step will show you how to save the state of a container as a new Docker image.

After installing NodeJS inside the Ubuntu container, you now have a container running from an image, but the container is different from the initial image which you have used to create it.

To save the new state of the container as a new image, first exit from it:

exit

Then commit the changes to a new Docker image instance by using the following command. The -m switch is for the commit message that helps you and others know what changes you have made, while the -a switch is used to specify the author. The container ID is the one you have noted earlier in the tutorial when you started the interactive docker session. Unless you have created additional repositories on Docker Hub, the repository is usually your Docker Hub username:

docker commit -m "<^>What did you do to the image<^>" -a "<^>Author Name<^>" <^>container-id repository/new_image_name<^>

For example:

docker commit -m "<^>added node.js<^>" -a "<^>Dockerian Expert<^>" <^>669d7e624344 myid/ubuntu-nodejs<^>

<$>[note] Note: When you commit an image, the new image is saved locally on your computer. <$>

Once the operation has completed, listing the Docker images on your computer should show the new image, as well as the initial one which was used to initiate it:

docker images

The output should be similar to this:

[secondary_label Output]
myid/ubuntu-nodejs       latest              d4a6a3ff7b09        12 seconds ago      208 MB
ubuntu              latest              8b72bba4485f        27 hours ago          120 MB
hello-world         latest              05a3bd381fc2        33 hours ago         1.84kB

In the above example, ubuntu-nodejs is the new image, which was derived from the existing ubuntu image from Docker Hub. The size difference reflects the changes that were made i.e. the installation of NodeJS. So next time you need to run a container using Ubuntu with NodeJS pre-installed, you can just use this new image.

Step 7 — Listing Docker Containers

After using Docker for a while, you may have many active (running) and inactive containers on your computer. To view the active ones, use:

docker ps

You will see output similar to the following:

[secondary_label Output]
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
669d7e624344        ubuntu              "/bin/bash"         3 hours ago         Up 3 hours                              trusting_turing

To view all containers — active and inactive, pass it the -a switch:

docker ps -a

To view the latest container you have created, pass it the -l switch:

docker ps -l

To stop a running or active container, execute:

docker stop container-id

The container-id can be found in the output from the docker ps command.

Conclusion

This tutorial is just an introduction to Docker. There is more which you can do with Docker. For more information, visit the official Docker documentation site.