Mastering Docker Installation on Linux: Key Commands for a Seamless Setup
Docker forms the backbone of container platform deployments, and a misconfigured install can halt a CI/CD pipeline before the first image is built. For repeatable results, engineers should rely on direct, explicit commands—no shortcuts.
Typical Failure Mode
Consider spinning up a fresh Ubuntu node for a CI runner. You follow a two-year-old blog, run apt-get install docker
, and get version 20.x. A pipeline later fails with failed to create shim task: OCI runtime create failed: ... version mismatch
.
Lesson: Package managers often lag behind Docker’s official repo.
Pre-Install: System Preparation
Update package indices to avoid missing dependencies:
sudo apt-get update # Ubuntu/Debian
sudo yum update -y # CentOS/RHEL 7/8
sudo dnf update -y # Fedora
—Do not proceed with stale package lists unless you want dependency nightmares.
Ubuntu/Debian: Clean Install Using Official Repository
Remove legacy Docker bits (they'll conflict):
sudo apt-get remove docker docker-engine docker.io containerd runc
Install transport prerequisites:
sudo apt-get install -y ca-certificates curl gnupg lsb-release
Add Docker’s GPG key and repo (determine which LTS codename to use if you’re scripting):
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
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
Update again; the Docker repo is now present:
sudo apt-get update
Install current engine components; at time of writing, this yields Docker CE 24.x:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
Verify version:
sudo docker --version
Example output:
Docker version 24.0.2, build cb74dfc
Note: Expect to see “Docker Engine - Community” in systemctl status docker
; if you see a version prior to 24, verify your repository steps.
CentOS/RHEL: Official Repository Only
First, strip previous versions:
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest \
docker-latest-logrotate docker-logrotate docker-engine
Add Docker’s YUM repository:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Install Docker Engine:
sudo yum install -y docker-ce docker-ce-cli containerd.io
Start and enable the daemon (monitor logs on first start for selinux errors):
sudo systemctl start docker
sudo systemctl enable docker
Confirm:
docker --version
Gotcha: On CentOS 7, containerd.io
packages sometimes fail due to obsolete kernel features. Check /var/log/messages
for cgroup errors.
Fedora: DNF Workflow
Purge old Docker packages if present:
sudo dnf remove docker docker-client docker-client-latest docker-common \
docker-latest docker-latest-logrotate docker-logrotate docker-engine
Install DNF plugin and configure repo:
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
Install Docker:
sudo dnf install -y docker-ce docker-ce-cli containerd.io
Start/enable:
sudo systemctl start docker
sudo systemctl enable docker
Check:
docker --version
Known issue: Starting with Fedora 31, cgroup driver defaults to cgroupfs
—for Kubernetes compatibility, consider systemd
(edit /etc/docker/daemon.json
).
Optional: Manage Docker as Non-Root (Recommended for Automation & CI)
By default, only root
can run Docker. Grant your user permission:
sudo groupadd docker # Only if the group doesn't exist
sudo usermod -aG docker $USER
This change takes effect after re-login, but in automation scenarios, invoke with:
newgrp docker
Test with:
docker run hello-world
Tip: On some cloud images (Debian GCP), default users are not in docker
—post-provision step required in your cloud-init or Terraform.
Troubleshooting: Practical Scenarios
-
Service fails to start:
Examine withsudo journalctl -u docker
— look for overlay2, selinux, or cgroup errors. -
Permission denied (socket):
Error:Got permission denied while trying to connect to the Docker daemon socket
Fix with user group as above, or exploit
sudo
. -
Conflicting systemd unit:
If containerd is running separately (systemctl status containerd
), Docker start may fail. Stop standalonecontainerd
before restarting Docker. -
Legacy kernel:
Docker requires kernel 4.x+. On CentOS 7,yum update kernel
and reboot if the default is too old.
Quick Reference
Task | Command(s) |
---|---|
Update package index | sudo apt-get update |
Remove old Docker | apt-get remove docker docker-engine ... |
Add official repository | as shown above (varies per distro) |
Install Docker | sudo apt-get install docker-ce docker-ce-cli containerd.io |
Start & enable service | sudo systemctl start docker && sudo systemctl enable docker |
Grant user non-root access | sudo usermod -aG docker $USER |
Test with hello-world | docker run hello-world |
Final Observations
Blanket installs (apt install docker
) are rarely sufficient for production. Engineers should always test Docker Engine startup, version, and network bridge post-install. When installing at scale (e.g., with Ansible), script robust error checking around each step.
Reference this set when you need to bootstrap a node for container workloads—not everything here is perfect (edge cases abound on non-LTS releases), but it will save hours on first install and in postmortems.
Side note: If you require a specific Docker version (e.g., 23.0.6 due to compatibility), append =<version>
after package names during install, and verify all dependencies match.
Practical example:
Building a Jenkins agent image in a brand-new Ubuntu 22.04 VM, these steps yield a consistent base for downstream containers—no surprises mid-pipeline.
Keep this as your checklist. Production deploys depend on predictable tooling, and nowhere is that truer than Docker on Linux.