Installing Docker on Ubuntu 18.04 Using Snap
I recently revisited the installation of Docker, this time on my Ubuntu 18.04 virtual machine. I decided to use Snap this time to get the latest release of Docker and associated utilities. Here are the steps.
-
Install docker.
sudo snap install docker
-
Verify the docker version.
$ docker --version Docker version 18.06.1-ce, build e68fc7a $ docker.compose --version docker-compose version 1.22.0, build unknown
Note that docker compose becomes available as
docker.compose
and not asdocker-compose
. This is due to Snap naming restrictions. -
Create the
docker
group and add my user account to it.sudo addgroup --system docker sudo adduser $USER docker newgrp docker
-
Restart docker to activate the group change.
sudo snap disable docker sudo snap enable docker
-
Verify that docker is running by confirming that there are no images running.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE
I then proceeded to install and run the hello-world
docker image, just to
double-check the installation.
-
Create a working directory for the new image.
mkdir -p ~/Workspace/docker/hello-world cd ~/Workspace/docker/hello-world
-
Create a docker configuration file with the following content.
$ cat docker-compose.yml tests: image: hello-world
-
Run the
hello-world
container.$ docker.compose up Pulling hello-world (hello-world:)... latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:92695bc579f31df7a63da6922075d0666e565ceccad16b59c3374d2cf4e8e50e Status: Downloaded newer image for hello-world:latest Creating hello-world_tests_1 ... done Attaching to hello-world_tests_1 hello-world_1 | hello-world_1 | Hello from Docker! hello-world_1 | This message shows that your installation appears to be working correctly. hello-world_1 | hello-world_1 | To generate this message, Docker took the following steps: hello-world_1 | 1. The Docker client contacted the Docker daemon. hello-world_1 | 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. hello-world_1 | (amd64) hello-world_1 | 3. The Docker daemon created a new container from that image which runs the hello-world_1 | executable that produces the output you are currently reading. hello-world_1 | 4. The Docker daemon streamed that output to the Docker client, which sent it hello-world_1 | to your terminal. hello-world_1 | hello-world_1 | To try something more ambitious, you can run an Ubuntu container with: hello-world_1 | $ docker run -it ubuntu bash hello-world_1 | hello-world_1 | Share images, automate workflows, and more with a free Docker ID: hello-world_1 | https://hub.docker.com/ hello-world_1 | hello-world_1 | For more examples and ideas, visit: hello-world_1 | https://docs.docker.com/get-started/ hello-world_1 | hello-world_tests_1 exited with code 0
-
Verify that the container is registered locally now.
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 01f4d8ae5337 hello-world "/hello" 52 seconds ago Exited (0) 51 seconds ago hello-world_tests_1
That’s it! … but there is more thing that requires attention.
Fixing DNS in the Containers #
Run the following command to verify that the containers resolve host names properly:
$ docker run --rm -it alpine ping -c3 debian.org
ping: bad address 'debian.org'
The command instantiates the alpine
docker image and runs the ping command
inside to access the debian.org
host. In the example above, the container
fails to resolve the host name.
By default, when docker instantiates an image it copies the DNS resolver file
/etc/resolv.cof
from the host into the new container. In Ubuntu 18.04, this
file is a symlink:
$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Apr 20 2018 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
$ cat /etc/resolv.conf
nameserver 127.0.0.53
options edns0
search fosstel.com
The resolver file points to a DNS cache available at the address 127.0.0.53. This cache does not work inside the container and this is the reason why it fails to resolve the host name.
One way to solve this problem is to change the symlink to point to the real resolver file, as follows:
$ sudo rm /etc/resolv.conf
$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
You can run the ping test command again to verify that host resolution works:
$ docker run --rm -it alpine ping -c3 debian.org
PING debian.org (149.20.4.15): 56 data bytes
64 bytes from 149.20.4.15: seq=0 ttl=47 time=31.471 ms
64 bytes from 149.20.4.15: seq=1 ttl=47 time=28.204 ms
64 bytes from 149.20.4.15: seq=2 ttl=47 time=28.709 ms
--- debian.org ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
There are other ways to change the way DNS resolution happens inside the
containers. One of them is to modify the docker default values by editing the
file /snap/docker/current/config/daemon.json
and adding the following line, as
an example:
"dns": ["8.8.8.8", "8.8.4.4"]
You may want investigate this and possible other options.