How to Install Docker on Ubuntu 18.04: Complete Step-by-Step Installation and Configuration Guide

how to Install Docker on Ubuntu 18.04

Ubuntu 18.04 LTS (Bionic Beaver) reached end of standard support some time ago, but I still run into it regularly on legacy servers, older cloud images, and long-lived internal infrastructure that hasn’t been upgraded yet. Installing Docker on it works essentially the same way as on any modern Ubuntu release, with a couple of version-availability caveats worth knowing up front. This guide walks through a clean install from scratch.

Prerequisites

  • A machine or VM running Ubuntu 18.04 LTS with sudo access
  • An internet connection for package downloads
  • At least 20GB of free disk space (Docker images accumulate quickly)

Check your Ubuntu version first:

lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.6 LTS
Release:        18.04
Codename:       bionic

Step 1: Remove Any Old Docker Packages

Older Ubuntu installs sometimes have outdated packages like docker, docker-engine, or docker.io from the default Ubuntu repos, which conflict with Docker’s official builds:

sudo apt-get remove docker docker-engine docker.io containerd runc
Package 'docker' is not installed, so not removed
Package 'docker-engine' is not installed, so not removed

That output is expected on a clean system — it confirms nothing conflicting is present.

Step 2: Update Package Index and Install Prerequisites

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

Step 3: Add Docker’s Official GPG Key

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Step 4: Add the Docker APT Repository

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

Verify the file:

cat /etc/apt/sources.list.d/docker.list
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu bionic stable

Note bionic correctly reflects the 18.04 codename, pulled automatically from lsb_release -cs.

Step 5: Install Docker Engine

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Expected output (abbreviated):

Setting up containerd.io (1.7.20-1) ...
Setting up docker-ce-cli (5:27.3.1-1~ubuntu.18.04~bionic) ...
Setting up docker-ce (5:27.3.1-1~ubuntu.18.04~bionic) ...
Setting up docker-buildx-plugin (0.17.1-1~ubuntu.18.04~bionic) ...
Setting up docker-compose-plugin (2.29.2-1~ubuntu.18.04~bionic) ...

Step 6: Verify Docker Is Running

sudo systemctl status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2026-07-29 10:44:12 UTC; 30s ago
sudo docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

Step 7: Manage Docker as a Non-Root User

Running every command with sudo gets old fast. Add the current user to the docker group:

sudo usermod -aG docker $USER

Log out and back in, or apply the group change to the current shell session without logging out:

newgrp docker

Verify:

docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

No sudo needed this time.

Step 8: Configure Docker to Start on Boot

sudo systemctl enable docker.service
sudo systemctl enable containerd.service
Synchronizing state of docker.service with SysV service script.
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service.

Step 9: Confirm Compose Is Available

docker compose version
Docker Compose version v2.29.2

A Note on Ubuntu 18.04’s Kernel Version

Ubuntu 18.04 shipped originally with a 4.15 kernel, later updated via HWE (Hardware Enablement) stacks to newer kernels. Docker requires certain kernel features (namespaces, cgroups, overlay filesystem support) that are all present by 4.15, but some newer Docker features (like certain cgroup v2-only behaviors) assume a newer kernel than 18.04 ships by default. Check your running kernel:

uname -r
5.4.0-192-generic

If this looks unusually old (like a bare 4.15.x without HWE updates), I’d upgrade the kernel via the HWE stack before relying on Docker in anything beyond a test environment:

sudo apt-get install --install-recommends linux-generic-hwe-18.04

Internal Working: What “Installing Docker” Actually Installs

The docker-ce package I installed above is really a bundle of several cooperating components:

  • containerd: a high-level container runtime that manages container lifecycle, image transfer, and storage, originally split out of Docker itself and now a CNCF graduated project used by Docker, Kubernetes, and others.
  • runc: the low-level OCI-compliant runtime that actually creates namespaces, sets up cgroups, and executes the container process.
  • dockerd: the Docker daemon, which exposes the Docker API, manages images/volumes/networks, and delegates actual container execution down to containerd and runc.
  • docker-ce-cli: the docker command-line client that talks to dockerd over its Unix socket (or TCP, if configured).
  • docker-buildx-plugin and docker-compose-plugin: CLI plugins that add docker build (BuildKit-powered) and docker compose subcommands.

When I run docker run hello-world, the CLI sends a request to dockerd, which asks containerd to pull the image and create a container, which in turn calls runc to actually fork and exec the isolated process using Linux namespaces and cgroups.

Networking Considerations

On installation, Docker creates a default bridge network (docker0) and configures iptables rules for NAT so containers can reach the internet and have their published ports (-p) forwarded from the host. On Ubuntu 18.04, this requires iptables (not nftables exclusively) to be functioning correctly — the default 18.04 install uses iptables-legacy, which Docker handles natively without extra configuration.

Storage Considerations

Docker’s default storage driver on modern kernels is overlay2, which requires the overlay kernel module (present by default on 18.04’s kernel). Verify:

docker info | grep "Storage Driver"
Storage Driver: overlay2

Docker’s data (images, containers, volumes) lives under /var/lib/docker by default — worth monitoring disk usage on this path over time:

sudo du -sh /var/lib/docker
2.1G    /var/lib/docker

Security Considerations

  • Since Ubuntu 18.04 is past its standard support window, ensure Docker itself is kept current even if the base OS receives fewer updates, and consider Ubuntu’s Extended Security Maintenance (ESM) if you must stay on 18.04 for compatibility reasons.
  • Membership in the docker group is equivalent to root access on the host — treat it with the same caution as sudo access.
  • Regularly run docker system prune cautiously (after reviewing what it will remove) to avoid accumulating stale images that may contain outdated, vulnerable packages:
docker image prune -a --filter "until=720h"

Troubleshooting

“E: Unable to locate package docker-ce” Almost always means the repository wasn’t added correctly, or apt-get update wasn’t re-run after adding it. Recheck:

cat /etc/apt/sources.list.d/docker.list
sudo apt-get update

“Got permission denied while trying to connect to the Docker daemon socket” The current shell session hasn’t picked up the new docker group membership yet. Use newgrp docker or log out and back in.

Docker service fails with cgroup-related errors Check GRUB kernel parameters include cgroup support and reboot after any change:

cat /proc/cgroups

Monitoring

docker stats --no-stream
docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          3         1         412.3MB   298.1MB (72%)
Containers      1         1         0B        0B
Local Volumes   1         1         5.2MB     0B (0%)

Best Practices

  • Always remove distro-default Docker-adjacent packages before installing Docker’s official build.
  • Pin the specific Docker version in production via apt-get install docker-ce=<version> for reproducibility.
  • Keep the kernel updated via HWE stacks on long-lived 18.04 hosts.
  • Enable both docker.service and containerd.service on boot.
  • Regularly audit /var/lib/docker disk usage and prune unused images/volumes.

Summary

Installing Docker on Ubuntu 18.04 follows Docker’s standard APT-based installation process almost identically to newer Ubuntu releases — add the GPG key, add the repository (correctly resolved to bionic), and install the docker-ce package family. The main things worth double-checking on an older release like 18.04 are kernel version/HWE status, iptables mode, and planning for the fact that the OS itself is past standard support even though Docker on it works exactly as documented.

References

  • Docker Engine installation for Ubuntu: https://docs.docker.com/engine/install/ubuntu/
  • Docker post-installation steps for Linux: https://docs.docker.com/engine/install/linux-postinstall/
  • containerd documentation: https://containerd.io/docs/
  • Ubuntu 18.04 Extended Security Maintenance: https://ubuntu.com/security/esm
Total
0
Shares

Leave a Reply

Previous Post
Adding and Removing Users with useradd, usermod, and userdel in Red Hat

Adding and Removing Users with useradd, usermod, and userdel in Red Hat

Next Post
Cyber Security and hacking

Cyber Security and hacking data info graphic trend in 2023

Related Posts