Install Docker Engine on Linux (Ubuntu, Debian, Fedora, Arch)

Quick facts
What you installDocker Engine (dockerd), the docker CLI, containerd, and the Compose and Buildx plugins
Ubuntu / DebianDocker's APT repository (docker-ce) or the distro's docker.io
FedoraDocker's RPM repository (docker-ce) or Fedora's moby-engine; Podman preinstalled
Archdocker, docker-compose, docker-buildx in the official repositories
Servicedocker.service and docker.socket (systemd)
Data directory/var/lib/docker (rootless: ~/.local/share/docker)
Documentationdocs.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
The docker group is root-equivalent

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

SymptomCauseFix
Cannot connect to the Docker daemon at unix:///var/run/docker.sockDaemon not runningsudo systemctl enable --now docker; check journalctl -u docker -b
permission denied … docker.sockNot in docker group / not re-logged inSee the fix page
bind: address already in useHost port takenFind it with sudo ss -tlpn 'sport = :8080'; see Address already in use
Disk full, /var/lib/docker hugeOld images, build cache, stopped containersdocker system df, then docker system prune (add -a for unused images; --volumes deletes data); see No space left on device
Containers can't resolve namesHost uses 127.0.0.53, or VPN DNSSet "dns": ["9.9.9.9"] in /etc/docker/daemon.json and restart Docker
Published ports reachable despite ufw rulesDocker writes its own firewall rules, which bypass ufwPublish only to localhost ("127.0.0.1:8080:80") or filter in the DOCKER-USER chain
docker-compose: command not foundOld standalone tool not installedUse 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.