Docker Engine supports 64‑bit Ubuntu releases including 24.10 (Oracular), 24.04 LTS (Noble), and 22.04 LTS (Jammy) on architectures such as amd64 (x86_64), arm64, armhf, s390x, and ppc64le. Docker relies on the kernel’s iptables backend and works with the iptables-nft or iptables-legacy interfaces; rules created directly with the nft tool aren’t honored by Docker networking. If you manage a host firewall with ufw or firewalld, be aware that publishing container ports bypasses many host-level rules. Add allow/deny policy to the DOCKER-USER chain to enforce filtering before Docker’s rules.

Before installing, remove any conflicting distro packages to avoid version clashes. Unofficial packages like docker.io, legacy docker-compose, or previously installed containerd/runc can block a clean setup.

Step 1: Remove old or conflicting packages.

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove -y "$pkg"; done

Step 2: Confirm your Ubuntu release and architecture so you add the correct repository.

source /etc/os-release && echo "Ubuntu codename: ${UBUNTU_CODENAME:-$VERSION_CODENAME}"; dpkg --print-architecture

Method 1: Install Docker Engine from Docker’s apt repository

This method installs the latest stable Docker Engine and plugins through apt, making future updates straightforward via your package manager.

Step 1: Install required packages and add Docker’s GPG key using a modern keyring path (avoids deprecated apt-key usage).

sudo apt-get update
sudo apt-get install -y 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

Step 2: Add Docker’s repository, then refresh package indexes.

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

Step 3: Install Docker Engine, CLI, containerd, Buildx, and Compose plugin.

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

Step 4: Confirm the service is running and run the test container.

sudo systemctl status docker --no-pager
sudo docker run hello-world

Step 5: Allow your user to run Docker without sudo (optional but convenient). This adds your account to the docker group, which has root-equivalent access to the Docker daemon—only add trusted users.

sudo usermod -aG docker $USER
newgrp docker  # or log out and back in
docker run hello-world

Step 6: Upgrade later using apt. You can pin to a specific version if you need to match an environment.

# Show available engine versions
apt-cache madison docker-ce | awk '{ print $3 }'

# Install a specific version (example version string)
VERSION_STRING=5:28.3.3-1~ubuntu.24.04~noble
sudo apt-get install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin

Method 2: Install from downloaded .deb packages (offline/manual upgrades)

Use this when hosts can’t access the repository or when you need a reproducible offline install. You’ll manually download matching .deb files for your Ubuntu release and architecture.

Step 1: Browse to Docker’s Ubuntu repository in a browser and choose your release under dists/. Then open pool/stable/<arch>/ (e.g., amd64 or arm64).

Step 2: Download the following packages that match the same version:

  • containerd.io_<version>_<arch>.deb.
  • docker-ce_<version>_<arch>.deb.
  • docker-ce-cli_<version>_<arch>.deb.
  • docker-buildx-plugin_<version>_<arch>.deb.
  • docker-compose-plugin_<version>_<arch>.deb.

Step 3: Install the packages with dpkg. Replace paths with where you downloaded the files.

sudo dpkg -i ./containerd.io_*_*.deb \
  ./docker-ce_*_*.deb \
  ./docker-ce-cli_*_*.deb \
  ./docker-buildx-plugin_*_*.deb \
  ./docker-compose-plugin_*_*.deb

Step 4: Start the service if it didn’t start automatically and verify with the test image.

sudo service docker start
sudo docker run hello-world

Maintenance tip: Repeat the download and install when you need to upgrade; manual installs don’t follow apt’s regular updates.


Method 3: Install with Docker’s convenience script (fast setup for dev/test)

The script at get.docker.com detects your distro and installs Docker non‑interactively. It’s quick but opinionated and not designed for production upgrades.

Step 1: Preview what the script will do.

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh --dry-run

Step 2: Run the script to install the latest stable Docker Engine, containerd, and runc.

sudo sh ./get-docker.sh

Step 3: Verify and, optionally, configure non-root usage.

sudo docker run hello-world
sudo usermod -aG docker $USER && newgrp docker

Caution: Re-running the script to upgrade can leave dependencies at unexpected versions. Use your package manager for ongoing upgrades after the initial bootstrap.


Optional: Install Docker Desktop on Ubuntu (GUI)

Docker Desktop bundles a GUI, Docker Engine, Docker CLI, Docker Compose V2, and optional Kubernetes for developer workflows. It requires Ubuntu 22.04, 24.04, or the latest non‑LTS on x86‑64. Non‑GNOME desktops should install gnome-terminal to support integrated terminals. Commercial use in larger enterprises may require a paid subscription as per Docker’s terms.

Step 1: Set up Docker’s package repository (same keyring and repo step used in Method 1) so dependencies resolve cleanly.

# If not already configured:
sudo apt-get update
sudo apt-get install -y 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
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

Step 2: Download the Docker Desktop .deb for Linux (amd64) and install it.

# Example for amd64; replace with the file you downloaded
sudo apt-get install -y ./docker-desktop-amd64.deb

Step 3: Start Desktop and set it to auto-start if you like.

# Start for current user session
systemctl --user start docker-desktop

# Enable on login (optional)
systemctl --user enable docker-desktop

Notes: Docker Desktop creates a dedicated Docker context to avoid clashing with any local Engine on the host. For server environments, running Docker Engine alone is typically simpler and avoids Desktop dependencies.


Post‑install checks and common tasks

Verify Docker works: Pulling and running the test image proves the daemon, network, and registry access are functioning.

docker run hello-world

Run a quick web container: Map a host port to confirm port publishing works:

docker run -d -p 8080:80 --name web nginx
docker ps

Start on boot (Engine on servers): Ensure the daemon starts after reboots.

sudo systemctl enable docker

Troubleshooting

Deprecated apt-key warnings: Use the keyring approach shown above (/etc/apt/keyrings/docker.asc) instead of apt-key. This removes the warning and keeps the key scoped to Docker’s repo.

GPG key fetch errors (no route, proxy, or TLS issues): Check outbound 443 connectivity, corporate proxies, or DNS. If behind a proxy, set https_proxy/http_proxy for your shell and for curl. Verify you can reach https://download.docker.com/ with a simple curl -I.

docker: command not found: The CLI isn’t installed or isn’t in your PATH. Reinstall the packages from Method 1 or verify /usr/bin/docker exists.

Cannot connect to the Docker daemon: Ensure the service is running and you’re in the docker group if running without sudo.

sudo systemctl status docker
sudo systemctl start docker
sudo usermod -aG docker $USER && newgrp docker

Image pulls hang or fail with TLS handshake timeout: Check Internet routing, DNS, or corporate proxy configuration. Synchronize system time (NTP) since large skews can break TLS. Retest with a lightweight image like hello-world to isolate registry access issues.

UFW/firewalld and published ports: Docker’s nat/forward rules can bypass host firewall policies for published ports. Put allow/deny rules in the DOCKER-USER chain so they’re evaluated before Docker rules. Also ensure your system uses an iptables interface Docker supports (nft or legacy) rather than raw nft rules.

WSL without systemd: If you see “System has not been booted with systemd,” manage Docker via Docker Desktop for Windows or enable systemd in your WSL distro settings. Direct systemctl commands won’t work without systemd.


Uninstall Docker Engine completely

Step 1: Remove packages.

sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

Step 2: Delete Docker data directories (this removes images, containers, volumes).

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Step 3: Remove the repo and keyring if you won’t reinstall.

sudo rm -f /etc/apt/sources.list.d/docker.list
sudo rm -f /etc/apt/keyrings/docker.asc

With Docker installed and verified, you can start containers immediately and manage them with Compose or Buildx as needed. Keep your system time accurate, watch firewall behavior, and update through apt to stay current with security fixes.