Installing Docker CE on Ubuntu 18.04
Ubuntu's docker.io package lags several releases behind, and its packaging doesn't match what Docker's own documentation assumes. I got tired of "works in the docs, not on my box", so on anything I plan to keep I use Docker CE from Docker's apt repository (18.09 right now). After that, upgrades are just apt upgrade.
Below: Docker CE and docker-compose on Ubuntu 18.04 (64-bit, sudo user, outbound HTTPS to download.docker.com), non-root access, and a few daemon defaults before the first container runs.
Remove old versions
If the machine ever had the distribution packages, remove them first so the two do not conflict:
sudo apt remove -y docker docker-engine docker.io containerd runc
It is fine if none of them are installed; apt just says so. Images and containers under /var/lib/docker are left in place.
Add Docker's apt repository
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
The fingerprint output should end in 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88. Then add the stable channel for your architecture and release:
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
lsb_release -cs expands to bionic on 18.04.
Install Docker CE
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
The service is enabled and started by the package. Check:
sudo systemctl status docker
sudo docker version
The client and server should both report 18.09.x. If you need to stay on a specific version, list what is available and pin it:
apt-cache madison docker-ce
sudo apt install -y docker-ce=5:18.09.2~3-0~ubuntu-bionic docker-ce-cli=5:18.09.2~3-0~ubuntu-bionic containerd.io
sudo apt-mark hold docker-ce docker-ce-cli
Running docker without sudo
The package creates a docker group. Members can talk to the daemon socket, which is root on the host for all practical purposes, so I only add accounts I'd also trust with sudo.
sudo usermod -aG docker $USER
Log out and back in for the group to take effect, then docker ps should work without sudo.
Daemon defaults
I put these in /etc/docker/daemon.json on every host before running anything: log rotation, because the default json-file driver grows without limit (a chatty container filled a disk on me once), and the overlay2 storage driver, already the default on 18.04 but nice to see written down.
sudo nano /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
sudo systemctl restart docker
docker info | grep -E 'Storage Driver|Logging Driver'
docker-compose
docker-compose is a separate program shipped as a single binary. Ubuntu's packaged version is older than what current Compose files expect, so I fetch the release from GitHub:
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose version
Smoke test
docker run --rm hello-world
You want Hello from Docker!. Then something with a port, to check that publishing and DNS inside the container work:
docker run -d --name web-test -p 8080:80 nginx:1.15-alpine
curl -I http://localhost:8080
docker rm -f web-test
If it misbehaves
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock. Your user is not in thedockergroup yet, or you have not logged out since being added.id -nGshows the effective groups of the current session.E: The repository 'https://download.docker.com/linux/ubuntu bionic Release' does not have a Release file. Usually a typo in theadd-apt-repositoryline, orarch=amd64on an ARM machine. Check/etc/apt/sources.list.d/for the generated entry.- Containers cannot resolve DNS. The daemon copies the host's
/etc/resolv.confinto containers, and on 18.04 that points at127.0.0.53(systemd-resolved), which Docker detects and replaces with Google's servers. If your network blocks those, set"dns": ["10.0.0.2"]indaemon.json. - ufw rules are bypassed by published ports. Docker manages its own iptables chains. Publish only to localhost (
-p 127.0.0.1:8080:80) when a service should not be reachable from outside, and put a reverse proxy in front.
I keep daemon.json in configuration management now, so no host starts without log rotation.