Docker Installation on Ubuntu

Docker on Ubuntu should be installed from Docker's official repository, not Ubuntu's package repositories. The version in Ubuntu's repos is typically 2-3 major versions behind the current release and lacks important security patches. The snap package is also not recommended for production use — it runs in a snap confinement that creates subtle differences in file paths and behavior. This guide covers the correct installation path for a production Ubuntu Docker host.

Docker CE vs Snap installation

MethodVersionRecommended for
Docker CE (official repo)Latest stableProduction use
Ubuntu apt repos2-3 versions oldNot recommended
SnapRecent but sandboxedQuick testing only

Installing Docker CE

# Remove any old Docker packages:
sudo apt remove docker docker-engine docker.io containerd runc

# Install dependencies:
sudo apt update
sudo apt install -y ca-certificates curl gnupg

# Add Docker's official GPG key:
sudo install -m 0755 -d /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

# Add Docker repository:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]   https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" |   sudo tee /etc/apt/sources.list.d/docker.list

# Install Docker:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Verify:
sudo docker run hello-world

Post-install configuration

# Allow non-root user to run docker (adds to docker group):
sudo usermod -aG docker $USER
newgrp docker    # Apply without logging out

# Test without sudo:
docker ps

# Enable Docker to start on boot:
sudo systemctl enable docker

# Configure Docker daemon settings:
sudo nano /etc/docker/daemon.json

/etc/docker/daemon.json — recommended production settings

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "live-restore": true
}

# live-restore: containers keep running if dockerd restarts
# log rotation: prevents container logs from filling disk
# overlay2: default storage driver for Ubuntu (faster than devicemapper)
sudo systemctl restart docker

System tuning for Docker hosts

# Enable memory cgroup v2 (required for memory limiting in newer Docker):
# In /etc/default/grub, add cgroup parameters:
# GRUB_CMDLINE_LINUX="cgroup_memory=1 cgroup_enable=memory swapaccount=1"
sudo update-grub
# Reboot required

# Set system-wide resource limits for Docker containers:
sudo nano /etc/sysctl.d/99-docker.conf

/etc/sysctl.d/99-docker.conf

vm.max_map_count=262144      # Required for Elasticsearch in Docker
net.core.somaxconn=65535     # Increase connection backlog for high-traffic containers
sudo sysctl -p /etc/sysctl.d/99-docker.conf

Conclusion

Always install Docker from the official Docker repository for production systems. Configure /etc/docker/daemon.json with log rotation immediately — without it, long-running containers accumulate logs in /var/lib/docker/containers/ indefinitely and fill the disk. Enable live-restore: true so a Docker daemon restart does not stop running containers during an upgrade.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Work with Muhammad Irfan Aslam