Installing Docker on Linux
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:
- Add user to docker group:
sudo usermod -aG docker $USER - Log out and back in
- 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:
- Check available storage drivers:
docker info - Set appropriate driver in
/etc/docker/daemon.json - 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 Docker concepts: the object model in one page
- Docker images and containers
- Dockerfile basics: build your first image
- Docker volumes: keep data past the container
Key takeaways
- Use Docker's official repository, not the distro's
docker.iopackage, which lags well behind. - Install the plugins too:
docker-buildx-pluginanddocker-compose-plugingive you BuildKit anddocker compose. usermod -aG docker $USERneeds a new login. Groups are read at login, so an open shell keeps the old set.- The
dockergroup is effectively root on that host. Consider rootless mode on shared machines. systemctl enable --now dockeror it will not come back after a reboot.- Set log rotation in
daemon.json. The defaultjson-filedriver has no size limit and will fill the disk. - On SELinux systems, bind mounts need
:zor:Z, or the container gets permission denied on files that look readable.
Check your understanding
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.