Installing Docker on Linux

By Vishvesh Patel · DevOps EngineerUpdated September 16, 2026

Install Docker Engine from the official repository on Ubuntu, Debian, RHEL and Fedora, plus the post-install steps that stop you needing sudo.

Linux is the one platform that runs containers natively, no virtual machine, no Docker Desktop required. You install Docker Engine from Docker's own repository and you are done.

One thing to get right before you start: do not install the docker.io or docker package from your distribution's default repository. Those are usually several releases behind, and on some distributions docker is an unrelated system-tray application. The instructions below add Docker's official repository, which is what keeps you current and lets apt upgrade or dnf upgrade maintain it.

Prerequisites

Before installing Docker on Linux, ensure your system meets these requirements:

Linux Requirements

  • 64-bit OS: Most modern distributions supported
  • Kernel: Version 3.10 or higher
  • RAM: Minimum 2GB (4GB recommended)
  • Storage: 10GB minimum for Docker images and containers

Installing Docker on Ubuntu/Debian

Step 1: Update Package Index

sudo apt-get update

Step 2: Install Prerequisites

sudo apt-get install \
    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: Set Up 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: Install Docker Engine

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

Step 6: Verify Installation

sudo docker run hello-world

Installing Docker on CentOS/RHEL

Step 1: Install Required Packages (CentOS)

sudo yum install -y yum-utils

Step 2: Add Docker Repository (CentOS)

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Step 3: Install Docker (CentOS)

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Step 4: Start Docker (CentOS)

sudo systemctl start docker
sudo systemctl enable docker

Step 5: Verify Installation (CentOS)

sudo docker run hello-world

Installing Docker on Fedora

Step 1: Install Prerequisites (Fedora)

sudo dnf -y install dnf-plugins-core

Step 2: Add Docker Repository (Fedora)

sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo

Step 3: Install Docker (Fedora)

sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Step 4: Start Docker (Fedora)

sudo systemctl start docker
sudo systemctl enable docker

Step 5: Verify Installation (Fedora)

sudo docker run hello-world

Post-Installation Steps

Running Docker Without sudo

By default, Docker requires root privileges. To run Docker as a non-root user:

Step 1: Create Docker Group

sudo groupadd docker

Step 2: Add Your User to Docker Group

sudo usermod -aG docker $USER

Step 3: Log Out and Back In

For the changes to take effect, log out and log back in. Or run:

newgrp docker

Step 4: Verify

docker run hello-world

You should now be able to run Docker commands without sudo.

Configure Docker to Start on Boot

Ubuntu/Debian/Fedora (systemd)

sudo systemctl enable docker.service
sudo systemctl enable containerd.service

CentOS/RHEL 7 and earlier

sudo chkconfig docker on

Configure Docker Daemon

Create or edit /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}

Restart Docker after making changes:

sudo systemctl restart docker

Troubleshooting Linux Installation

Docker Service Not Starting

Problem: "Failed to start docker.service"

Solution:

# Check service status
sudo systemctl status docker

# View logs
sudo journalctl -u docker

# Restart service
sudo systemctl restart docker

Permission Denied Error

Problem: "Got permission denied while trying to connect to the Docker daemon socket"

Solution:

  1. Add user to docker group: sudo usermod -aG docker $USER
  2. Log out and back in
  3. Or use: newgrp docker

Firewall Issues

Problem: Cannot pull images due to firewall

Solution:

# For firewalld
sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --reload

# For UFW
sudo ufw allow 2375/tcp
sudo ufw allow 2376/tcp

Storage Driver Issues

Problem: "Error starting daemon: error initializing graphdriver"

Solution:

  1. Check available storage drivers: docker info
  2. Set appropriate driver in /etc/docker/daemon.json
  3. Common drivers: overlay2 (recommended), aufs, devicemapper

Testing Your Installation

Let's verify everything works correctly:

1. Check Docker Version

docker --version
docker compose version

2. View System Information

docker info

This displays:

  • Number of containers (running, paused, stopped)
  • Number of images
  • Storage driver information
  • System resources

3. Run a Test Container

docker run -d -p 8080:80 nginx

Then visit http://localhost:8080 in your browser or use curl:

curl http://localhost:8080

You should see the Nginx welcome page!

4. List Running Containers

docker ps

5. Stop and Remove the Container

docker stop $(docker ps -q)
docker rm $(docker ps -aq)

Linux-Specific Configuration

SELinux Considerations (CentOS/RHEL/Fedora)

If using SELinux:

# Check SELinux status
getenforce

# Set SELinux to permissive mode for testing
sudo setenforce 0

# Make it permanent (edit /etc/selinux/config)
SELINUX=permissive

For production, configure proper SELinux policies instead of disabling it.

AppArmor Considerations (Ubuntu/Debian)

Docker works with AppArmor by default. If you encounter issues:

# Check AppArmor status
sudo aa-status

# Reload AppArmor profiles
sudo systemctl reload apparmor

Resource Limits

Configure resource limits in /etc/docker/daemon.json:

{
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 64000,
      "Soft": 64000
    }
  }
}

Docker Compose on Linux

Docker Compose is now included as a plugin. Verify:

docker compose version

If you need standalone Docker Compose:

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Best Practices for Linux

1. Keep Docker Updated

# Ubuntu/Debian
sudo apt-get update && sudo apt-get upgrade docker-ce docker-ce-cli

# CentOS/RHEL
sudo yum update docker-ce docker-ce-cli

# Fedora
sudo dnf upgrade docker-ce docker-ce-cli

2. Monitor Resource Usage

# View container resource usage
docker stats

# View disk usage
docker system df

3. Clean Up Regularly

# Remove unused images
docker image prune

# Remove all unused resources
docker system prune -a

4. Configure Logging

Prevent logs from filling disk:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

5. Use systemd for Management

# Start Docker
sudo systemctl start docker

# Stop Docker
sudo systemctl stop docker

# Restart Docker
sudo systemctl restart docker

# View Docker status
sudo systemctl status docker

Uninstalling Docker

If you need to remove Docker:

Ubuntu/Debian

sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

CentOS/RHEL/Fedora

sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Where to go next


Key takeaways

  • Use Docker's official repository, not the distro's docker.io package, which lags well behind.
  • Install the plugins too: docker-buildx-plugin and docker-compose-plugin give you BuildKit and docker compose.
  • usermod -aG docker $USER needs a new login. Groups are read at login, so an open shell keeps the old set.
  • The docker group is effectively root on that host. Consider rootless mode on shared machines.
  • systemctl enable --now docker or it will not come back after a reboot.
  • Set log rotation in daemon.json. The default json-file driver has no size limit and will fill the disk.
  • On SELinux systems, bind mounts need :z or :Z, or the container gets permission denied on files that look readable.

Check your understanding

Exercise

A disk that fills up on its own

A long-running container on an Ubuntu server gradually consumes all free disk space. The application writes no files. Everything goes to stdout. What is the usual cause?


Frequently Asked Questions

Should I install docker.io or docker-ce on Ubuntu?

docker-ce, from Docker's own repository. The docker.io package in Ubuntu's archive is maintained by Debian and typically trails upstream by a significant margin, sometimes missing BuildKit features and the Compose v2 plugin entirely. Adding Docker's repository, the GPG key and sources.list.d entry in the steps above, means you get current releases and ordinary apt upgrade keeps them current. Note also that the bare docker package is an unrelated system-tray application, not what you want.

How do I run Docker without sudo on Linux?

sudo usermod -aG docker $USER, then log out and back in, or run newgrp docker to get a shell with the new membership immediately. The step people miss is that supplementary groups are attached at login, so the shell you ran usermod in still has the old list and will keep failing. Do understand the security implication: a member of the docker group can mount the host root filesystem into a privileged container, so this is equivalent to passwordless root on that machine. On a shared server, rootless mode is the better answer.

Why does Docker keep filling up my disk?

Two causes, both fixable. Container logs are the sneaky one. The default json-file driver has no size cap, so stdout accumulates indefinitely under /var/lib/docker/containers. Set max-size and max-file in /etc/docker/daemon.json and restart the daemon, remembering that the setting applies to containers created afterwards. The other is unused images, build cache and dangling volumes: docker system df shows what is reclaimable and docker system prune -a --volumes removes it.

Do I need Docker Desktop on Linux?

No. Linux runs containers natively against the host kernel, so Docker Engine alone does everything, and that is what servers and CI runners use. Docker Desktop for Linux exists and adds a GUI, a VM for consistency with colleagues on other platforms, and a bundled Kubernetes, but it also brings the commercial licence terms that Docker Engine does not have. Unless you specifically want those features, install the engine.

Why do bind mounts give permission denied on CentOS, RHEL or Fedora?

SELinux. The host directory is labelled in a way the container's process type cannot read, so files that look perfectly readable are refused. Append :z to the mount to relabel it as shared between containers, or :Z for private to this one, -v /data:/data:z. Do not disable SELinux to work around it; the relabel option exists precisely for this and takes one character. The same applies to Podman on these distributions.

How do I completely uninstall Docker from Linux?

Remove the packages, then the data directories, because purging the package deliberately leaves your images and volumes behind. On Debian and Ubuntu: sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin, then sudo rm -rf /var/lib/docker /var/lib/containerd. On RHEL-family systems substitute dnf remove for the first command. That second step deletes every image, container and named volume on the machine, so confirm nothing there is wanted before running it.

Continue Learning

Explore Related Topics

Try the Tool

Practise this in the browser

Docker Playground

Run the commands in a simulated terminal, no install needed.

When it breaks

Related Resources