Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Install Docker on Linux

Step 4 of Docker series: hands-on guide to installing Docker Engine on Linux. Covers prerequisites, step-by-step setup, common pitfalls, and connections to next lessons.

Focus: install docker engine on linux

Sponsored

You've read about containers, imagined isolated environments for your apps, but every time you try to actually run Docker, you hit a wall with installation errors, missing dependencies, or confusing package managers. Without Docker Engine properly installed on Linux, none of the rest of the container journey — images, volumes, networks — is possible. This lesson gives you a repeatable, reliable method to install Docker Engine on Linux so you can start building and shipping containers today.

The problem this lesson solves

Installing Docker Engine on Linux seems simple until you run apt-get install docker.io and end up with an outdated version, or follow a random blog post that breaks your kernel. The core pain points are:

  • Out-of-repo versions: Default repositories (apt, yum) often ship very old Docker packages.
  • Incomplete installs: Missing the docker-ce (Community Edition) daemon or the containerd runtime.
  • Permission hell: Running docker ps without sudo fails with cryptic "permission denied" errors.
  • Conflicting packages: Previous attempts leave behind broken docker, docker.io, or docker-engine packages.

This lesson eliminates those pain points by using Docker's official repository — the same source used by CI/CD pipelines and production servers.

Core concept / mental model

Think of Docker Engine as three interlocking parts, like a three-layer cake:

  1. Docker daemon (dockerd) – the background service that manages containers, images, networks, and storage. It listens for API requests and does the heavy lifting.
  2. containerd – the low-level container runtime that actually runs processes inside namespaces and cgroups. Docker daemon delegates to it.
  3. Docker CLI (docker) – the client tool you type commands into. It talks to the daemon over a local UNIX socket (/var/run/docker.sock) or a network API.

When you install "Docker Engine," you're getting all three pieces. The CLI is your steering wheel, the daemon is the engine block, and containerd is the fuel injector.

Pro tip: Think of the Docker repository as a vending machine. Instead of hunting for packages across the internet, you add one official vending machine to your system, then pull exactly the versions you need.

How it works step by step

Installing Docker Engine on Linux follows a predictable six-step recipe, regardless of your distro (Ubuntu, Debian, CentOS, Fedora). The steps are:

  1. Uninstall old versions – remove any docker, docker.io, docker-engine packages that might conflict.
  2. Update package index – refresh your local package database.
  3. Install prerequisites – add packages like ca-certificates, curl, gnupg, and lsb-release that make the next steps work.
  4. Add Docker's official GPG key – cryptographically sign the packages so your system trusts them.
  5. Add the Docker repository – point your package manager at Docker's own repo for the latest stable releases.
  6. Install Docker Engine – use apt-get install docker-ce docker-ce-cli containerd.io (or the equivalent yum / dnf commands).

After installation, you must start the daemon (systemctl start docker) and verify it works (docker run hello-world). Finally, add your user to the docker group to avoid typing sudo before every command.

Pro tip: The group addition (sudo usermod -aG docker $USER) only takes effect after you log out and back in. Use newgrp docker in the same terminal session to bypass a reboot.

Hands-on walkthrough

Below are complete, runnable examples for Ubuntu/Debian and CentOS/RHEL. Follow one set based on your distro.

Example 1: Install on Ubuntu 22.04 (Debian-based)

# Step 1: Uninstall old versions
sudo apt-get remove docker docker-engine docker.io containerd runc

# 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

# Step 4: Add the 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

# Step 5: Update and install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Step 6: Start and verify
sudo systemctl start docker
sudo docker run hello-world

Expected output at the end:

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

Example 2: Install on CentOS 9 (RHEL-based)

# Step 1: Uninstall old versions
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

# Step 2: Install prerequisites
sudo yum install -y yum-utils

# Step 3: Add repository
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# Step 4: Install Docker Engine
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Step 5: Start daemon and enable on boot
sudo systemctl start docker
sudo systemctl enable docker

# Step 6: Verify with non-root run (skipping sudo test)
sudo docker run hello-world

Example 3: Post-install – running Docker without sudo

After the base install, you want to avoid sudo for everyday commands:

# Add your user to the docker group
sudo usermod -aG docker $USER

# Activate group change without logout
newgrp docker

# Verify
id -nG   # output should include 'docker'
docker run hello-world   # should work without sudo

Pro tip: If you see Got permission denied while trying to connect to the Docker daemon socket, you missed the group step or didn't reload. Run newgrp docker again.

Example 4: Verify installation with a simple container

# In your terminal, run a quick container to check everything works
import subprocess
result = subprocess.run(['docker', 'ps', '--all'], capture_output=True, text=True)
print(result.stdout)

Expected output (initially empty, but no error):

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Compare options / when to choose what

Installation method Pros Cons Best for
Official repository (this lesson) Latest stable, GPG-signed, automatic updates Requires internet, few commands All production and development setups
Scripted install (get.docker.com) One-liner, minimal user interaction Less transparency, may not respect pinned versions Quick prototyping, CI pipelines
Distro package (apt install docker.io) No GPG setup needed Usually outdated (e.g., Docker 20.10 vs 24.0+) Learning environments where cutting-edge not needed
Static binaries No package manager dependency Manual upgrades, no daemon management Air-gapped or embedded systems

Choose the official repository for 90% of cases — it's the most maintainable. Use the convenience script for one-shot demos. Avoid the distro package unless you're on an LTS that backports (rare).

Troubleshooting & edge cases

Below are the most common issues after [install docker engine on linux] and how to fix them.

"Error: Package 'docker-ce' has no installation candidate"

Your repository configuration is missing or the architecture is wrong.

# Re-add the repository with correct architecture
sudo rm /etc/apt/sources.list.d/docker.list
echo \
  "deb [arch=amd64 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
sudo apt-get update

"Cannot connect to the Docker daemon"

Daemon isn't running, or your user can't access the socket.

sudo systemctl status docker   # check if active
sudo systemctl start docker    # if inactive
ls -la /var/run/docker.sock    # should be owned by root:docker
sudo usermod -aG docker $USER && newgrp docker

"docker: permission denied while trying to connect"

You haven't added your user to the docker group, or you need to log out and back in.

sudo usermod -aG docker $USER
newgrp docker

Repository not found for Ubuntu arm64 / Raspberry Pi

The official repository supports arm64, but the URL is the same. Use arch=arm64 in the deb line. For 32-bit ARM (armhf), use the same repo — Docker images exist for those platforms.

Conflict with podman or containerd

Remove them first:

sudo apt-get remove podman runc   # Debian
sudo yum remove podman containerd.io   # RHEL

What you learned & what's next

You now understand that [install docker engine on linux] means setting up the Docker daemon, containerd, and CLI from Docker's official repository. You can: - Uninstall conflicting older packages. - Add the GPG key and repository for your specific distro. - Install, start, and verify the latest Docker Engine. - Run Docker commands without sudo by joining the docker group.

This foundation unlocks the rest of the Docker learning path. In the next lesson, you'll pull your first image and run a container with custom ports and volumes. You'll take the Engine you just installed and make it actually serve an application.

Pro tip: After verifying the install, run docker info to see system-wide details — Swarm status, storage driver, CPU/memory limits, and more. It's the quickest health check.

Practice recap

Your mini exercise: Uninstall any existing Docker packages, then follow the six-step official repository install for your Linux distro. After installation, run docker info and capture the output. Next, run docker run -d -p 80:80 nginx and visit http://localhost in a browser — you should see the Nginx welcome page. This confirms the engine, networking, and image pulling all work. If you hit errors, refer to the troubleshooting section above.

Common mistakes

  • Installing docker.io from Ubuntu's default repo (which is often months behind) instead of Docker's official repository.
  • Forgetting to add the user to the docker group and then running sudo docker — works but every command needs sudo, and scripts break.
  • Not removing old packages like docker-engine or runc before installing Docker CE, causing version conflicts or silent failures.
  • Running systemctl start docker before adding the repository — the daemon won't exist yet, leading to misleading 'service not found' errors.
  • Copying the GPG key step but using --output flag incorrectly — the --dearmor flag is required to convert from ASCII armor to binary.

Variations

  1. Use the convenience script (curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh) for a one-command install, but be aware it lacks manual control over version pinning.
  2. For a rootless installation (no daemon running as root), follow Docker's rootless mode guide after the basic install — useful for multi-tenant environments.
  3. Use apt-get install docker.io on Debian stable if you prefer a slower but more conservative release cadence backed by your distro's security team.

Real-world use cases

  • Setting up a local development environment where every team member runs the same containerized stack (e.g., PostgreSQL + Redis + Node.js) by first installing Docker Engine on each Linux workstation.
  • Provisioning a fresh CI runner on Ubuntu Server so that every build pipeline can run docker build and docker push commands without permission errors.
  • Deploying a production Docker host on CentOS that runs web services behind a reverse proxy — the install method you choose directly affects update frequency and security patch timelines.

Key takeaways

  • Docker Engine is a three-part stack: daemon, containerd runtime, and CLI — you must install all three from Docker's official repo for the latest stable version.
  • Always uninstall old docker, docker.io, and docker-engine packages before installing Docker CE to avoid conflicts.
  • The official repository install requires adding a GPG key and a sources.list entry — this ensures signed, verified packages.
  • After installation, add your user to the docker group (sudo usermod -aG docker $USER) and use newgrp docker to avoid sudo requirement.
  • Verify installation with docker run hello-world — if it prints a welcome message, the daemon, CLI, and network are all working correctly.
  • The official repository method is preferred over scripts or distro packages for production, as it allows pinning versions and integrating with existing update mechanisms.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.