Install and Configure Docker Engine on Ubuntu

1. Overview

Duration 2:00

What is a container?

Containers are a solution to the problem of how to get software to run reliably when moved from one computing environment to another. How does it work?, well it bundles an application’s code together with the related configuration files and libraries, and with the dependencies required for the app to run. This allows us to deploy applications seamlessly across environments.

What do we need to create and work with containers?

  1. Builder: Its a tool used to build, in the case of Docker is a DockerFile which is a text document that contains all the commands a user could call on the command line to assemble an image.

  2. Engine: It is an application used to run a container. For Docker, this refers to the docker command and acts like a client and the dockerd daemon which acts as a server. It is called the Docker Engine.

  3. Orchestration: If we need to deploy many containers a technology used to manage many containers is needed. This process includes provisioning, deployment, scaling (up and down), networking, load balancing and more. A good example would be Kubernetes.

In this tutorial we will be focusing on the Docker Engine.

What you’ll learn

  • How to install Docker from the regular Ubuntu repository.
  • How to enable Docker to start automatically at system boot.
  • How to install Docker images and run them locally.
  • How to configure Docker.
  • How to search and run images from docker hub.

What you’ll need.

  • Ubuntu 18.04(LTS) , 20.04 (LTS), 21.04, or 21.10.
  • User with administrator privileges.
  • Basic Command-line knowledge.

Note: For This procedure we will use Ubuntu Focal 20.04 (LTS).

If you don’t have Ubuntu installed you can follow this How to Install Ubuntu Tutorial.

Or you can also install Ubuntu on a virtual machine with this tutorial.

What is your current level of experience?

  • Novice
  • Intermediate
  • Proficient
0 voters

2 Prepare the Installation.

Duration 3:00

Removing old Installation and files.

Let’s remove some older installations of docker, just in case!. This way we make sure to have a clean installation. If you are sure you don’t have docker installed go the the installation process.

sudo apt-get remove docker docker-engine docker.io containerd runc

The apt-get command should remove packages related to docker if they were installed.

if passages were removed we need to make sure that the contents in the directory /var/lib/docker/ is not preserved. To do this follow these steps:

To uninstall the Docker Engine, CLI, and Containerd packages:

sudo apt-get purge docker-ce docker-ce-cli containerd.io

To delete all images, containers, and volumes:

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Add the repository.

In this tutorial will be installing the docker engine using the Ubuntu repositories

Let’s begin!

Set up the repository:

sudo apt update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release

This command will update the apt package index, this way we can use apt to use the repository over https.

Add Docker’s official GPG key.

 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Note: GPG is a public key cryptography implementation. This allows for the
secure transmission of information between parties and can be used to verify
that the origin of a message is genuine.

Use the following command to set up the stable repository

 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

We can verify the repository has been added

ls -al /etc/apt/sources.list.d | grep docker

3 Docker Engine Installation

Duration 3:00

Steps:

1 Update apt package index.

apt update

2 Install the latest version of Docker Engine.

sudo apt-get install docker-ce docker-ce-cli containerd.io

Note
If you have multiple Docker repositories enabled, installing or updating without
specifying a version in the apt-get install or apt-get update command
always installs the highest possible version, which may not be appropriate for
your stability needs.

In case you need to install a specific version, follow these two steps…

1 Verify the available version in the repository.

apt-cache madison docker-ce

Lets say we want to install the version available 5:20.10.5~3-0~ubuntu-focal

2 Run the installation command.

sudo apt-get install docker-ce=5:20.10.5~3-0~ubuntu-focal docker-ce-cli=5:20.10.5~3-0~ubuntu-focal containerd.io

Now that we have installed the docker engine version that we need we can test the docker engine by downloading and running an docker image:

sudo docker run hello-world

4. Post Installation Configurations

Duration 5:00

At this point we can work normally with the docker engine. However, it is recommended to verify and configure certain aspects to work more comfortably.

Verify Docker engine starts at boot.

sudo systemctl list-unit-files --type=service | grep docker.service

If the second column “STATE” is enabled means that the docker service will start at boot.

If the STATE column is disabled we can enable it by running this command.

sudo systemctl enable docker.service

Use docker as a non-root user.

The Docker daemon always runs as the root user. This means that a regular user needs to use sudo to access this service.

If you don’t want to preface the docker command with sudo, follow these steps:

  1. Create a docker group. (In case it doesn’t exist)
sudo groupadd docker
  1. Add your user to the docker group.
sudo usermod -aG docker $USER
  1. Activate the changes to groups.
 newgrp docker
  1. Verify that you can run docker commands without sudo.
docker run hello-world

Here is the sequence:

:warning: Important
The docker group grants privileges equivalent to the root user.
This can make your system vulnerable to docker daemon attacks.

Configure where the Docker daemon listens for connections.

It is possible to allow Docker to accept requests from remote hosts by configuring it to listen on an IP address and port as well as the UNIX socket.

The recent versions of Ubuntu uses systemd, this means that we can configure docker to accept remote connections with the docker.service unit-file.

Lets see How this works!!!

1.Edit the docker.service file.

sudo systemctl edit docker.service

Lets say we want to listen for connections from any remote host on port 2376

2. we need to add this lines:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376

3. Write the changes (ctrl-o) and exit (ctrl-x).

4. Reload the systemctl configuration.

sudo systemctl daemon-reload

5. Restart the Docker service.

sudo systemctl restart docker.service

6. Verify the dockerd daemon listening on the configured port using the netstat command.

sudo netstat -lntp | grep dockerd

here is the sequence:

Enable IPv6 support

If we need to use ipv6 with docker you can follow these steps. We can choose to use either IPv4 or IPv6 (or both) with any container, service, or network.

###1. Edit the daemon.json file in /etc/docker/ or create it if it doesn’t exist.

In the daemon.json file:

  • In the file set the ipv6 key to true
  • The fixed-cidr-v6 to your IPv6 subnet.
{
  "ipv6": true,
  "fixed-cidr-v6": "<YOUR-IPV6-SUBNET>"
}
  • Save the file.

2. Reload the Docker configuration file.

systemctl reload docker

Specify DNS servers for Docker.

1. Create or edit the Docker daemon configuration file.

sudo nano /etc/docker/daemon.json

2. Add a DNS key.

{
  "dns": ["8.8.8.8", "8.8.4.4"]
}

:warning: Note:
Make sure to include at least one DNS server which can resolve
public ip addresses, so that you can connect to Docker Hub and so that your
containers can resolve internet domain names.

Save and close the file.

3. Restart the Docker daemon.

sudo service docker restart

4. Verify that Docker can pull an image.

docker pull hello-world

5 That’s all folks!

Very easy, wasn’t it?

Congratulations!

You made it!

If you have been watching closely, you are now fully equipped to install Docker Engine.

Now you know how to:

  • Perform a clean install of Docker Engine.
  • Perform additional configurations to customize the installation
2 Likes

Sorry if I shouldn’t post this here or if I’m a standard edge case, but What should I do with this? Docker stopped working for me late last year. I’ve been reaching out for some clarity every so often since then, but just get :cricket:'s.
I only used Docker for Collabora for my Nextcloud instance.

Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-43-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Wed Apr 20 15:36:19 EDT 2022

  System load:  1.96              Processes:               463
  Usage of /:   45.5% of 1.79TB   Users logged in:         0
  Memory usage: 23%               IP address for enp2s0f0: 192.168.1.164
  Swap usage:   1%

  => There is 1 zombie process.

 * Super-optimized for small spaces - read how we shrank the memory
   footprint of MicroK8s to make it the smallest full K8s around.

   https://ubuntu.com/blog/microk8s-memory-optimisation

0 updates can be applied immediately.


Last login: Tue Dec 28 14:54:30 2021
admin@srv2:~$ sudo apt-get purge docker-ce docker-ce-cli containerd.io
[sudo] password for admin: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages were automatically installed and are no longer required:
  docker-scan-plugin pigz
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
  containerd.io* docker-ce* docker-ce-cli*
0 upgraded, 0 newly installed, 3 to remove and 0 not upgraded.
1 not fully installed or removed.
After this operation, 371 MB disk space will be freed.
Do you want to continue? [Y/n] Y
[master 0b8d19d] saving uncommitted changes in /etc prior to apt run
 Author: admin <admin@srv2>
 1 file changed, 1 insertion(+)
(Reading database ... 325066 files and directories currently installed.)
Removing docker-ce (5:20.10.14~3-0~ubuntu-bionic) ...
Removing containerd.io (1.5.11-1) ...
Removing docker-ce-cli (5:20.10.14~3-0~ubuntu-bionic) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
(Reading database ... 324847 files and directories currently installed.)
Purging configuration files for docker-ce (5:20.10.14~3-0~ubuntu-bionic) ...
Purging configuration files for containerd.io (1.5.11-1) ...
Processing triggers for systemd (237-3ubuntu10.53) ...
Processing triggers for ureadahead (0.100.0-21) ...
[master 608c363] committing changes in /etc after apt run
 Author: admin <admin@srv2>
 15 files changed, 294 deletions(-)
 delete mode 100644 containerd/config.toml
 delete mode 100644 default/docker
 delete mode 100755 init.d/docker
 delete mode 100644 init/docker.conf
 delete mode 120000 rc0.d/K01docker
 delete mode 120000 rc1.d/K01docker
 delete mode 120000 rc2.d/S01docker
 delete mode 120000 rc3.d/S01docker
 delete mode 120000 rc4.d/S01docker
 delete mode 120000 rc5.d/S01docker
 delete mode 120000 rc6.d/K01docker
 delete mode 120000 systemd/system/multi-user.target.wants/containerd.service
 delete mode 120000 systemd/system/multi-user.target.wants/docker.service
 delete mode 120000 systemd/system/sockets.target.wants/docker.socket
admin@srv2:~$ sudo apt remove docker-scan-plugin pigz
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  docker-scan-plugin pigz
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 13.5 MB disk space will be freed.
Do you want to continue? [Y/n] Y
(Reading database ... 324842 files and directories currently installed.)
Removing docker-scan-plugin (0.17.0~ubuntu-bionic) ...
Removing pigz (2.4-1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
admin@srv2:~$ sudo rm -rf /var/lib/docker
admin@srv2:~$ sudo rm -rf /var/lib/containerd
admin@srv2:~$ ls -al /etc/apt/sources.list.d | grep docker
-rw-r--r-- 1 root root  131 Apr 20 15:41 docker.list
admin@srv2:~$ sudo apt-get install docker-ce docker-ce-cli containerd.io
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  docker-scan-plugin pigz
The following NEW packages will be installed:
  containerd.io docker-ce docker-ce-cli docker-scan-plugin pigz
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/88.4 MB of archives.
After this operation, 384 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Selecting previously unselected package pigz.
(Reading database ... 324830 files and directories currently installed.)
Preparing to unpack .../archives/pigz_2.4-1_amd64.deb ...
Unpacking pigz (2.4-1) ...
Selecting previously unselected package containerd.io.
Preparing to unpack .../containerd.io_1.5.11-1_amd64.deb ...
Unpacking containerd.io (1.5.11-1) ...
Selecting previously unselected package docker-ce-cli.
Preparing to unpack .../docker-ce-cli_5%3a20.10.14~3-0~ubuntu-bionic_amd64.deb ...
Unpacking docker-ce-cli (5:20.10.14~3-0~ubuntu-bionic) ...
Selecting previously unselected package docker-ce.
Preparing to unpack .../docker-ce_5%3a20.10.14~3-0~ubuntu-bionic_amd64.deb ...
Unpacking docker-ce (5:20.10.14~3-0~ubuntu-bionic) ...
Selecting previously unselected package docker-scan-plugin.
Preparing to unpack .../docker-scan-plugin_0.17.0~ubuntu-bionic_amd64.deb ...
Unpacking docker-scan-plugin (0.17.0~ubuntu-bionic) ...
Setting up containerd.io (1.5.11-1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /lib/systemd/system/containerd.service.
Setting up docker-scan-plugin (0.17.0~ubuntu-bionic) ...
Setting up docker-ce-cli (5:20.10.14~3-0~ubuntu-bionic) ...
Setting up pigz (2.4-1) ...
Setting up docker-ce (5:20.10.14~3-0~ubuntu-bionic) ...
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service.
Created symlink /etc/systemd/system/sockets.target.wants/docker.socket → /lib/systemd/system/docker.socket.
Job for docker.service failed because the control process exited with error code.
See "systemctl status docker.service" and "journalctl -xe" for details.
invoke-rc.d: initscript docker, action "start" failed.
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: activating (auto-restart) (Result: exit-code) since Wed 2022-04-20 15:54:33 EDT; 10ms ago
     Docs: https://docs.docker.com
  Process: 17597 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=1/FAILURE)
 Main PID: 17597 (code=exited, status=1/FAILURE)
dpkg: error processing package docker-ce (--configure):
 installed docker-ce package post-installation script subprocess returned error exit status 1
Processing triggers for systemd (237-3ubuntu10.53) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for ureadahead (0.100.0-21) ...
Errors were encountered while processing:
 docker-ce
[master 20a1d9e] committing changes in /etc after apt run
 Author: admin <admin@srv2>
 15 files changed, 294 insertions(+)
 create mode 100644 containerd/config.toml
 create mode 100644 default/docker
 create mode 100755 init.d/docker
 create mode 100644 init/docker.conf
 create mode 120000 rc0.d/K01docker
 create mode 120000 rc1.d/K01docker
 create mode 120000 rc2.d/S01docker
 create mode 120000 rc3.d/S01docker
 create mode 120000 rc4.d/S01docker
 create mode 120000 rc5.d/S01docker
 create mode 120000 rc6.d/K01docker
 create mode 120000 systemd/system/multi-user.target.wants/containerd.service
 create mode 120000 systemd/system/multi-user.target.wants/docker.service
 create mode 120000 systemd/system/sockets.target.wants/docker.socket
E: Sub-process /usr/bin/dpkg returned an error code (1)

admin@srv2:~$ sudo systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Wed 2022-04-20 15:54:45 EDT; 10min ago
     Docs: https://docs.docker.com
  Process: 18599 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=1/FAILURE)
 Main PID: 18599 (code=exited, status=1/FAILURE)

Apr 20 15:54:45 srv2 systemd[1]: docker.service: Service hold-off time over, scheduling restart.
Apr 20 15:54:45 srv2 systemd[1]: docker.service: Scheduled restart job, restart counter is at 5.
Apr 20 15:54:45 srv2 systemd[1]: Stopped Docker Application Container Engine.
Apr 20 15:54:45 srv2 systemd[1]: docker.service: Start request repeated too quickly.
Apr 20 15:54:45 srv2 systemd[1]: docker.service: Failed with result 'exit-code'.
Apr 20 15:54:45 srv2 systemd[1]: Failed to start Docker Application Container Engine.