Install Docker Engine on Linux (Ubuntu, Debian, Fedora, Arch)
| What you install | Docker Engine (dockerd), the docker CLI, containerd, and the Compose and Buildx plugins |
| Ubuntu / Debian | Docker's APT repository (docker-ce) or the distro's docker.io |
| Fedora | Docker's RPM repository (docker-ce) or Fedora's moby-engine; Podman preinstalled |
| Arch | docker, docker-compose, docker-buildx in the official repositories |
| Service | docker.service and docker.socket (systemd) |
| Data directory | /var/lib/docker (rootless: ~/.local/share/docker) |
| Documentation | docs.docker.com/engine/install |
Docker Desktop for Linux exists too, but it runs containers inside a VM. On a Linux machine, Docker Engine is simpler and faster. Remove old or conflicting packages first if you've experimented before:
# Ubuntu / Debian: remove distro packages that conflict with docker-ce
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt remove -y $pkg; done
This leaves your images and volumes in /var/lib/docker untouched.
Install on Ubuntu 26.04 / 24.04
Add Docker's repository with its own key, the signed-by way (apt-key is gone in 26.04; see the apt guide for why):
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
On Linux Mint, UBUNTU_CODENAME makes this pick the Ubuntu base (for example noble for Mint 22.x) rather than Mint's own codename. If apt update reports that the repository has no Release file, Docker hasn't published packages for your release yet; see no Release file, or use Ubuntu's own packages in the meantime:
sudo apt install docker.io docker-compose-v2 docker-buildx
Package names in the Ubuntu archive can change between releases; check with apt search docker-compose.
Install on Debian 13
The same steps with the Debian URL:
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Debian's own docker.io package also works if you prefer packages from the Debian archive. On Debian the service starts automatically after install.
Install on Fedora
sudo dnf install dnf-plugins-core
sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
The addrepo --from-repofile syntax is for DNF5 (Fedora 41 and later). dnf will ask you to accept Docker's GPG key; check that the fingerprint matches the one in Docker's documentation. Right after a new Fedora release, Docker's repository can lag for a few weeks; Fedora's moby-engine package is the fallback. If you'd rather not run a daemon at all, Fedora's preinstalled Podman runs most images unchanged (podman run, podman compose).
Install on Arch and openSUSE
# Arch
sudo pacman -S docker docker-compose docker-buildx
sudo systemctl enable --now docker.service
# openSUSE Leap / Tumbleweed
sudo zypper install docker docker-compose
sudo systemctl enable --now docker
Both install the Compose v2 plugin, so docker compose works.
Post-install: verify and set up access
sudo systemctl status docker
sudo docker run --rm hello-world
docker compose version
Example output:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To run docker without sudo, add yourself to the docker group:
sudo usermod -aG docker $USER
# log out and back in (or reboot), then
docker run --rm hello-world
Anyone in the docker group can mount the host's root filesystem into a container and change anything. Only add trusted users. On shared or exposed machines, use rootless mode instead.
If you still get "permission denied while trying to connect to the Docker daemon socket", you haven't logged out yet or the group change didn't apply; see Docker socket permission denied. Never fix it with chmod 666 /var/run/docker.sock.
Rootless mode
Rootless Docker runs the daemon as your own user, so a container escape gets your privileges, not root's.
# Ubuntu / Debian
sudo apt install uidmap docker-ce-rootless-extras
# Fedora
sudo dnf install shadow-utils fuse-overlayfs docker-ce-rootless-extras
# stop the system daemon if you won't use it
sudo systemctl disable --now docker.service docker.socket
# set up and start the user daemon
dockerd-rootless-setuptool.sh install
systemctl --user enable --now docker
sudo loginctl enable-linger $USER # keep containers running after logout
The setup tool prints the DOCKER_HOST value to add to your shell profile. Limits: ports below 1024 need extra configuration, and some networking and storage features differ. Check that /etc/subuid and /etc/subgid contain a range for your user.
Docker Compose basics
Save this as compose.yaml:
services:
web:
image: nginx:stable
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
docker compose up -d # start in the background
docker compose ps
docker compose logs -f web
docker compose pull # update images
docker compose up -d # recreate with the new images
docker compose down # stop and remove containers (volumes are kept)
More commands are in the Docker commands cheat sheet. Containers with restart: unless-stopped come back after a reboot as long as docker.service is enabled; see systemd basics.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Cannot connect to the Docker daemon at unix:///var/run/docker.sock | Daemon not running | sudo systemctl enable --now docker; check journalctl -u docker -b |
permission denied … docker.sock | Not in docker group / not re-logged in | See the fix page |
bind: address already in use | Host port taken | Find it with sudo ss -tlpn 'sport = :8080'; see Address already in use |
Disk full, /var/lib/docker huge | Old images, build cache, stopped containers | docker system df, then docker system prune (add -a for unused images; --volumes deletes data); see No space left on device |
| Containers can't resolve names | Host uses 127.0.0.53, or VPN DNS | Set "dns": ["9.9.9.9"] in /etc/docker/daemon.json and restart Docker |
| Published ports reachable despite ufw rules | Docker writes its own firewall rules, which bypass ufw | Publish only to localhost ("127.0.0.1:8080:80") or filter in the DOCKER-USER chain |
docker-compose: command not found | Old standalone tool not installed | Use docker compose (space) |
To uninstall completely (this deletes every image, container and volume):
sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker /var/lib/containerd
Frequently asked questions
Should I install docker.io or docker-ce on Ubuntu?
docker-ce from Docker's repository is the newest upstream version and includes the Compose and Buildx plugins. docker.io is Ubuntu's own package, updated less often but supported through the Ubuntu archive. Either works; don't install both.
How do I run docker without sudo?
Add yourself to the docker group with sudo usermod -aG docker $USER and log out and back in. Be aware this is equivalent to root access; rootless mode is the safer alternative.
What is the difference between docker-compose and docker compose?
docker-compose (with a hyphen) is the old standalone Python tool. docker compose (with a space) is the current Compose v2 plugin. Use the plugin; your existing compose.yaml or docker-compose.yml files still work.
Should I use Podman instead of Docker on Fedora?
Podman is preinstalled on Fedora, runs rootless by default and accepts most Docker commands. It's a good default; install Docker when a tool specifically needs the Docker daemon or socket.
Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.