How to Install Docker on Ubuntu (26.04, 24.04): Step by Step

To install Docker on Ubuntu, add Docker's official repository through apt, install the docker-ce packages, and validate the installation with sudo docker run hello-world. The process takes around five minutes on a brand new server. This guide explains each step on Ubuntu 26.04 and 24.04, followed by the parts other tutorials usually omit: running Docker without sudo safely, the firewall hole Docker leaves, log management, and the errors you are most likely to see.
Short version (for those who know this process well):
sudo apt update && sudo apt 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
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
Before you install Docker on Ubuntu
Docker Engine supports the following 64-bit versions of Ubuntu, as Docker's install documentation states:
| Release | Codename | Status |
|---|---|---|
| Ubuntu 26.10 | Stonking | Interim release |
| Ubuntu 26.04 LTS | Resolute | Long-term support |
| Ubuntu 24.04 LTS | Noble | Long-term support |
| Ubuntu 22.04 LTS | Jammy | Long-term support |
On a server, select an LTS version. Supported architectures include x86_64 (amd64), arm64, armhf, s390x and ppc64le. Derivatives like Linux Mint are not officially supported, yet these steps usually work on them as well.
You need a user with sudo rights. If you still log in to the server as root, our tutorials on creating a user with a home directory and adding a user to sudoers take a couple of minutes.
Wondering which version you have? Run lsb_release -a or cat /etc/os-release. Our article on checking the Ubuntu version covers the other methods. The procedure is the same whether you install Docker on Ubuntu Server or on a desktop install; this article assumes a server you reach over SSH.
Step 1: Remove conflicting packages
Ubuntu's repositories include unofficial packages such as docker.io and docker-compose-v2. These conflict with the packages Docker provides, so uninstall them first:
sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)
On a fresh server, apt will report that none of them are installed. That's okay.
The removal doesn't delete any previously stored images, containers or volumes. They'll still be in /var/lib/docker/.
Step 2: Add Docker's apt repository
First install the tools apt needs, then download Docker's signing key:
sudo apt update
sudo apt 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
Add the repository now. Docker's current instructions use the deb822 format, a .sources file, rather than the one-line .list file of old:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
Because the Suites line picks up your release codename (noble, resolute and so on) by itself, these commands are identical on every supported version. Once apt update runs, download.docker.com should appear in its output.
Step 3: Install Docker Engine and Compose
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
That installs five packages:
| Package | What it is |
|---|---|
docker-ce | The Docker Engine daemon (dockerd) |
docker-ce-cli | The docker command |
containerd.io | The container runtime Docker runs on, with runc bundled |
docker-buildx-plugin | BuildKit-based docker buildx for building images |
docker-compose-plugin | Docker Compose v2, used as docker compose |
The Docker daemon starts automatically on Ubuntu and is enabled at system startup. Verify this with:
sudo systemctl status docker
To use a particular version rather than the most recent one, first run apt list --all-versions docker-ce to see which versions the repository contains, then give apt the version string, for example sudo apt install docker-ce=<version> docker-ce-cli=<version> containerd.io docker-buildx-plugin docker-compose-plugin.
Step 4: Check that Docker works
sudo docker run hello-world
Docker fetches a small test image, runs it in a container, displays a "Hello from Docker!" message and exits. If that message shows up, your engine, CLI and registry connection are all working.
You should also check the version numbers:
docker --version
docker compose version
Compose v2 is a plugin, hence the command is docker compose with a space. The legacy standalone docker-compose, with a hyphen, is not installed by these steps.
Step 5: Run Docker without sudo
By default, only the root user has access to the Docker daemon. To allow your own user to run the docker command, add it to the docker group:
sudo groupadd docker # usually exists already; an error here is harmless
sudo usermod -aG docker $USER
newgrp docker # or log out and back in
docker run hello-world
Make sure you understand what this does. Docker's official documentation makes it clear that membership of the docker group provides root-level privileges: any user in it can create a container that mounts the root filesystem of the host. Only add users to whom you would give root access anyway. For stronger isolation, Docker also offers rootless mode, where the daemon runs as an ordinary user.
Step 6: Harden the setup
Any server that runs Docker in earnest benefits from three changes.
Published ports bypass ufw. Publishing a port with -p 8080:80 makes Docker insert iptables rules of its own, ahead of ufw's. So a port ufw is supposed to block may in fact be open to the whole internet. Two habits avoid that:
For services only the server itself needs, bind to loopback with
-p 127.0.0.1:8080:80, and let a reverse proxy handle public traffic.Write custom firewall rules into the
DOCKER-USERiptables chain, which Docker leaves untouched. Onlyiptables-nftandiptables-legacyare supported; rulesets written in rawnftare not.
Rotate container logs. Docker's default logging driver, json-file, keeps every log line forever, and a noisy container can eat the disk bit by bit. Cap it in /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Apply it with sudo systemctl restart docker. Only containers created from now on get the cap, so recreate older ones to include them. Restarting the service also stops whatever is running (unless live restore is on), which is why it's best done before any workloads arrive.
Keep SSH secure. Installing Docker leaves SSH as it was, but a box running containers attracts attention. Key-only logins are covered in our tutorial on enabling and securing SSH on Ubuntu.
Install Docker Compose on Ubuntu
Everything above has already installed Docker Compose, via the docker-compose-plugin package. If an earlier install from Docker's repository left Compose out, add just the plugin:
sudo apt update
sudo apt install -y docker-compose-plugin
docker compose version
Where Docker came from Ubuntu's own docker.io package, the Compose package that goes with it is docker-compose-v2. Packages from the two sources clash when mixed, so either keep to Ubuntu's packages or switch everything over to Docker's repository as shown above.
Where Docker stores images
Fresh installs of Docker Engine 29 or newer hand images to containerd, which stores them under /var/lib/containerd rather than /var/lib/docker. According to Docker's documentation this image store takes more disk than the older storage drivers, since containerd holds every layer twice, compressed and unpacked. Size the root partition accordingly.
Moving Docker's data directory to another disk with data-root leaves containerd's storage where it was. Point containerd's own data directory at the new disk too, or the root partition can still run out of space. Servers that were upgraded from older Docker releases stay on the previous overlay2 layout under /var/lib/docker until you switch them.
Install with the convenience script (testing only)
Docker also publishes an install script at get.docker.com:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh --dry-run # shows what it would do
sudo sh ./get-docker.sh
Docker only recommends it for testing and development. It installs the most current version without asking, can jump major versions when you run it again, and is not meant to update an existing install. On a production server, use the apt repository described above.
Upgrading Docker
Because it is installed from an apt repository, Docker updates along with everything else on the system:
sudo apt update && sudo apt upgrade
If you want to keep Docker at its existing version, use sudo apt-mark hold docker-ce docker-ce-cli.
Common errors
permission denied while trying to connect to the Docker daemon socketEither the docker group change hasn't happened yet or your current session predates it. newgrp docker fixes the session; so does logging in again. Running the command with sudo also works.
docker-compose: command not foundThe hyphenated form belongs to the retired v1 tool. Type docker compose, with a space, to use the plugin.
E: Package 'docker-ce' has no installation candidateapt can't see Docker's repository. Confirm that /etc/apt/sources.list.d/docker.sources is there, re-run apt update, and double-check that your Ubuntu release appears in the supported list.
Conflicting values set for option Signed-BySome earlier install left a docker.list file pointing at another keyring. Remove that stale file from /etc/apt/sources.list.d/, then sudo apt update once more.
Cannot connect to the Docker daemon. Is the docker daemon running?The daemon is down. Bring it up with sudo systemctl start docker; if it dies again, the reason will be in journalctl -u docker.
What to do next
Now that Docker is in place, these guides cover what comes next:
Day-to-day work (starting, inspecting and debugging containers) is in the Docker commands cheat sheet.
Multi-container apps defined in a single file are the subject of Docker Compose up and down.
Images pile up over time; how to remove Docker images deals with that, and
docker system dftells you how bad it is.And if Docker ever has to come off the server, see how to uninstall Docker on Ubuntu.
Any OrbitServers VPS runs Docker comfortably, with full root access and NVMe storage from $39.99/mo, while bare metal suits heavier container workloads that need dedicated cores and no noisy neighbours.
Frequently asked questions
Should I install docker.io or docker-ce on Ubuntu?
Use the docker-ce package from Docker's repository. Ubuntu's docker.io package works too; however, it often lags behind Docker's releases and ships Compose separately. Docker's guide lists docker.io as a conflicting package to remove first.
Does this work on Ubuntu 22.04?
Yes. The commands work on 22.04, 24.04, 26.04 and 26.10, since the repository line enters your release codename automatically.
Is Docker Compose included?
Yes. Installing docker-compose-plugin gives you Compose v2, which you run as docker compose. Validate it with docker compose version.
Does Docker start automatically after a reboot?
On Ubuntu, yes: the Docker service starts automatically at boot. For your containers to come back after a reboot, they need a restart policy such as --restart unless-stopped.
Can I install Docker without root access?
Sudo is required to install the packages. After that, if your security rules require it, you can use rootless mode, where the Docker daemon runs as a regular user.
Do I need to reboot after installing Docker?
No. Docker is up and running as soon as apt finishes. The one change that waits for a new login is the docker group, and newgrp docker applies it in your current session.
What is the difference between Docker Engine and Docker Desktop?
Docker Engine, the subject of this guide, is the background daemon and the docker client you run on servers. Docker Desktop targets workstations (Windows, macOS and Linux): it packages the engine in a VM and puts a graphical app on top. Servers need nothing beyond Docker Engine.
Does Docker work on ARM64 servers?
Yes. There are arm64 builds for all supported Ubuntu releases, and since the repository line reads your architecture from dpkg --print-architecture, you get the right ones automatically.
Get started with Orbit Servers
Low-latency VPS, bare metal, and colocation across the US, EU, and APAC - provisioned instantly and built for performance-critical workloads.
Get startedRelated products
Written by
Julius
Product Manager
Julius is a product-minded builder who cares about making technology simpler and more useful for the people who rely on it. He’s always looking for ways to improve things, one small step at a time, and enjoys turning good ideas into products that work.