Why install Docker from the official repository

Ubuntu 24.04 ships a docker.io package in its universe repository, but it lags behind the official releases and misses Docker Compose v2 integration. Installing Docker Engine directly from Docker's official APT repository gives you the current stable version, the docker compose plugin, the BuildKit buildx plugin, and updates through apt like any other package. This guide walks you through the full official installation on Ubuntu 24.04 LTS (Noble Numbat), from prerequisites to a verified working setup.

Prerequisites

  • A server, VPS, or VM running Ubuntu 24.04 LTS. These steps also work on Ubuntu 22.04.
  • A user account with sudo access.
  • Internet access to reach download.docker.com and the Ubuntu mirrors.
  • About 10 minutes and roughly 500 MB of free disk space.

Step 1 - Update the package index

sudo apt update && sudo apt upgrade -y

apt update refreshes the local package lists so apt knows the newest versions. Upgrading first guarantees the system libraries the Docker packages depend on are current, which avoids half of the weird installation failures.

Step 2 - Install the prerequisites

sudo apt install -y ca-certificates curl

curl downloads Docker's GPG signing key over HTTPS, and ca-certificates lets the TLS handshake verify that you are really talking to download.docker.com and not an imposter.

Step 3 - Add Docker's official GPG key

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

The first command creates /etc/apt/keyrings with permissions 0755. The second downloads Docker's public signing key. The third makes the key file world-readable, which apt needs because the APT source line will reference it with signed-by. Storing the key in /etc/apt/keyrings is the modern, correct layout - the old apt-key approach is deprecated and can produce "key is stored in legacy trusted.gpg" warnings.

Step 4 - Add the Docker APT repository

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

This writes one line into /etc/apt/sources.list.d/docker.list. The $(. /etc/os-release && echo "$VERSION_CODENAME") part auto-detects your release codename, which resolves to noble on Ubuntu 24.04, so Docker's repository entry always matches your system. The stable suite pins you to production-ready Docker builds.

Step 5 - Install Docker Engine and the Compose plugin

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

The first apt update pulls the package lists from the new Docker repository you just added - skip it and apt will say it cannot find the packages. The five packages: docker-ce (the daemon and engine), docker-ce-cli (the docker command), containerd.io (the container runtime), docker-buildx-plugin (BuildKit builds), and docker-compose-plugin (the docker compose subcommand - no separate docker-compose binary needed).

Step 6 - Start and enable the Docker service

sudo systemctl enable --now docker

systemctl enable makes Docker start automatically on every boot, and --now also starts it immediately. Check the daemon is healthy with sudo systemctl status docker - you want to see active (running).

Step 7 - Run the hello-world test container

sudo docker run hello-world

This single command exercises the entire pipeline: Docker pulls the tiny hello-world image from Docker Hub, creates a container, runs it, prints the greeting, and exits. If you see the "Hello from Docker!" message, the engine, the runtime, and outbound networking all work.

Step 8 - Run Docker without sudo (optional, recommended)

sudo usermod -aG docker $USER
newgrp docker

usermod -aG docker adds your account to the docker group, which owns the Docker socket. newgrp docker applies the group membership to your current shell; a full logout/login does the same. After this, docker run hello-world works without sudo. Note the security trade-off: membership in the docker group is effectively equivalent to root access, so only add trusted accounts.

Verify your installation

Run these three commands; every one of them should succeed with no sudo (after Step 8):

docker version
docker compose version
docker run hello-world

docker version should print both Client and Server versions. docker compose version confirms the Compose plugin loaded (v2.x). The final hello-world run should reuse the cached image this time - note how fast it is compared to the first run, which had to download it.

Common issues and fixes

1. "permission denied" connecting to the Docker daemon socket

You ran docker as a user that is not in the docker group, or you did not refresh your login after joining it. Fix: repeat Step 8 and then log out and back in (or run newgrp docker). If you are on a headless server, a full new SSH session works too.

2. "Unable to locate package docker-ce"

apt does not know the Docker repository. Either you skipped the apt update after Step 4, or the .list file has a wrong codename. Verify with cat /etc/apt/sources.list.d/docker.list - it should contain noble on Ubuntu 24.04 - then run sudo apt update again.

3. GPG errors or "key is stored in legacy trusted.gpg"

The repository line must reference the key with signed-by=/etc/apt/keyrings/docker.asc, and the file must be readable (sudo chmod a+r /etc/apt/keyrings/docker.asc). If you followed an old tutorial that used apt-key add, remove the legacy key with sudo apt-key del and redo Step 3 and Step 4 the modern way.

4. Conflicts with Ubuntu's docker.io package

If docker.io or docker-compose from Ubuntu's universe repo is already installed, remove them first: sudo apt remove -y docker.io docker-compose docker-compose-v2 containerd runc. Mixing distribution packages with Docker's official packages is the most common source of broken containerd upgrades.

5. Docker does not start after a reboot

Run sudo systemctl is-enabled docker. If it says disabled, Step 6's enable flag never ran - fix it with sudo systemctl enable --now docker. If it is enabled but failed, sudo journalctl -u docker --no-pager | tail -n 30 will show the actual reason, which is usually a full disk or a broken storage directory under /var/lib/docker.

Keep Docker updated

Because you installed from Docker's official repository, updates arrive through apt like everything else. Run this regularly (weekly is a good cadence on production hosts):

sudo apt update && sudo apt upgrade -y

apt upgrade pulls the newest Docker Engine, CLI, containerd, and Compose plugin builds. After a major engine upgrade, restart the daemon with sudo systemctl restart docker so running containers pick up the new runtime. Compose files and images are not touched by package upgrades.

Bonus: completely remove Docker (if you ever need to)

sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo rm -rf /var/lib/docker /var/lib/containerd
sudo rm /etc/apt/sources.list.d/docker.list /etc/apt/keyrings/docker.asc

apt purge removes the packages and their config files. The rm -rf line deletes all images, containers, and volumes - skip it if you plan to reinstall and want to keep them. The last line removes the repository entry and the signing key, returning your apt sources to stock.

Conclusion

You now have the current Docker Engine, the Compose plugin, and BuildKit installed from the official repository on Ubuntu 24.04, running as a boot-enabled systemd service and verified with a test container. The natural next steps are learning docker compose files and setting up a small reverse proxy in front of your first containerized app.

Need server setup help? XpertBees configures Docker hosts, containerized deployments, and production hardening for businesses - reach out to our team and we will get your infrastructure running right.