How to Install Docker on Ubuntu 24.04 (Step-by-Step)

Install Docker on Ubuntu 24.04 with the official APT repository, Compose v2, a verified container, and fixes for common VPS errors on a fresh VPS.
A polished 3D server rack with glowing connected containers and an orange Ubuntu accent on a midnight-blue background.

Install Docker on Ubuntu 24.04 from Docker’s official APT repository and finish with Compose v2, non-root CLI access, and a working container test. On a fresh VPS, the setup and verification take about ten minutes.

Prerequisites

  • A 64-bit Ubuntu 24.04 LTS VPS with at least 2 GB of RAM and 10 GB of free disk space.
  • SSH access as root, or a normal Linux account with working sudo privileges.
  • Outbound HTTPS access to download.docker.com and Docker Hub so APT can retrieve packages and the test image.
  • No domain is needed for installation or the local web test. You will need a domain later if you put a public application behind HTTPS.
  • A VPSLake Linux VPS if you need a fresh Ubuntu server with root access.

The commands below use sudo for a normal SSH account. If you are logged in as root, remove sudo. Ubuntu 24.04 uses APT and commonly uses UFW; the Docker repository method below installs Docker Engine rather than Ubuntu’s separately packaged docker.io build.

Step 1: Confirm Ubuntu 24.04 and update the VPS

Checking the release and architecture first prevents you from adding a Noble repository to the wrong operating system.

grep -E '^(PRETTY_NAME|VERSION_ID|VERSION_CODENAME)=' /etc/os-release
uname -m
sudo apt update
sudo apt full-upgrade -y

The release should identify Ubuntu 24.04 and the architecture should normally be x86_64:

PRETTY_NAME="Ubuntu 24.04.x LTS"
VERSION_ID="24.04"
VERSION_CODENAME=noble
x86_64

The minor release and number of upgraded packages will vary. Fix any DNS, mirror, or interrupted-package error before continuing.

Step 2: Remove packages that conflict with Docker Engine

Ubuntu’s docker.io package, the older Compose package, and separately installed runtimes can conflict with Docker’s Engine package set.

On a new VPS, remove possible conflicting packages:

sudo apt remove -y docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc

APT may say that some packages are not installed; that is expected. This command does not automatically erase images, containers, volumes, or networks stored under /var/lib/docker/, so inspect existing workloads before changing a host that already runs containers.

Step 3: Add Docker’s signed Noble repository

The official repository supplies Docker Engine, its CLI, containerd, Buildx, and the maintained Compose plugin as a compatible package set.

Install the certificate tools, save Docker’s signing key in APT’s keyring directory, and create a deb822 source file for Ubuntu 24.04:

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 > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update

Confirm that APT sees an Engine candidate from Docker’s repository before installing it:

apt-cache policy docker-ce

The candidate should be listed under https://download.docker.com/linux/ubuntu and use the noble suite. Docker’s Ubuntu installation documentation documents this signed repository and package path.

Step 4: Install Docker Engine and Compose v2

Installing the daemon and plugins together keeps the Docker client, container runtime, image builder, and Compose integration aligned.

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker

Check the service and command-line tools immediately:

sudo systemctl is-active docker
sudo systemctl is-enabled docker
sudo docker version --format 'Client {{.Client.Version}} / Server {{.Server.Version}}'
sudo docker compose version

Expected output shows an active, enabled service and version strings. Docker publishes updates independently of Ubuntu’s point releases, so the numbers will change:

active
enabled
Client 29.x.y / Server 29.x.y
Docker Compose version v2.x.y

Step 5: Run Docker’s installation test

The hello-world image checks the complete path from the CLI to the daemon, registry, image cache, container creation, and process startup.

sudo docker run --rm hello-world

Near the end, look for this confirmation:

Hello from Docker!
Your installation appears to be working correctly.

The container exits after printing its message. The --rm flag removes its stopped container record, although the small image remains cached.

Step 6: Give one account non-root Docker access

Docker’s Unix socket is root-owned by default. Adding one trusted account to the docker group avoids repeated sudo, but group membership grants root-equivalent control over the VPS.

Run this as the normal account that should manage containers, replacing the placeholder with that account’s login name:

sudo groupadd --force docker
sudo usermod -aG docker YOUR_LINUX_USER

Log out of SSH completely and reconnect as that user so the new group is loaded. Then verify access without sudo:

id -nG
docker info --format 'Server {{.ServerVersion}}'

The group list should include docker, and the second command should print the Engine version. newgrp docker can load the group in the current shell, but reconnecting is less surprising when multiple SSH sessions are open.

Step 7: Test container networking on loopback

A disposable NGINX container verifies port publishing while binding only to the VPS’s loopback address, so the test does not require a DNS record or a public firewall rule.

docker run -d --name ubuntu2404-docker-check --publish 127.0.0.1:18083:80 nginx:alpine
docker ps --filter name=ubuntu2404-docker-check --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
curl --head --max-time 10 http://127.0.0.1:18083

You should see a running container and an HTTP success response:

NAMES                   STATUS        PORTS
ubuntu2404-docker-check Up ...        127.0.0.1:18083->80/tcp
HTTP/1.1 200 OK

Remove the disposable test after checking it:

docker stop ubuntu2404-docker-check
docker rm ubuntu2404-docker-check

Verify Docker on Ubuntu 24.04

Run this final check as the Docker administrator to confirm boot startup, daemon communication, Compose, and local storage:

systemctl is-active docker
systemctl is-enabled docker
docker version --format 'Client {{.Client.Version}} / Server {{.Server.Version}}'
docker compose version
docker info --format 'Containers {{.Containers}} | Images {{.Images}} | Storage {{.Driver}}'

Successful output includes active, enabled, client/server versions, a Compose v2 version, and usually overlay2 as the storage driver:

active
enabled
Client 29.x.y / Server 29.x.y
Docker Compose version v2.x.y
Containers 0 | Images 2 | Storage overlay2

For the way Docker’s published ports interact with host filtering, read the official packet-filtering and firewall guidance.

Troubleshooting

E: Package 'docker-ce' has no installation candidate

APT has not loaded Docker’s repository, or the source file points to a suite other than Noble. Check the release, source file, and package policy:

grep -E '^(VERSION_ID|VERSION_CODENAME)=' /etc/os-release
grep -E '^(Types|URIs|Suites|Components|Architectures|Signed-By):' /etc/apt/sources.list.d/docker.sources
sudo apt update
apt-cache policy docker-ce

The source must show Suites: noble, and the policy output should show a candidate from download.docker.com. Recreate Step 3 if the file is missing or names jammy or another release.

NO_PUBKEY or an APT signature verification error

APT cannot read the signing key associated with the Docker source. Download the key again and ensure APT can read it:

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 apt update

Do not bypass signature checks or mark the repository as trusted; the signature protects the package metadata.

permission denied while trying to connect to the Docker daemon socket

The current SSH process started before the account joined the docker group, or usermod targeted a different user. Reconnect, run id -nG, and retry; sudo docker info is only a temporary diagnostic while you correct the group membership.

curl: (7) Failed to connect to 127.0.0.1 port 18083

The NGINX image may still be downloading, the container may have exited, or another process may already own port 18083. Inspect the container and its logs:

docker ps -a --filter name=ubuntu2404-docker-check
docker logs ubuntu2404-docker-check
sudo ss -ltnp | grep ':18083'

If the port is occupied, remove the failed test and repeat it with --publish 127.0.0.1:28083:80, then request http://127.0.0.1:28083. A loopback-only binding does not need a UFW rule.

Hardening

  • Keep Docker’s API on its Unix socket. Never expose an unauthenticated Docker API on TCP port 2375; remote administration requires deliberate TLS configuration and narrow source-IP rules.
  • Treat membership in the docker group as administrative access. Use rootless Docker when the workload needs a stronger privilege boundary.
  • Bind internal applications to 127.0.0.1 until they sit behind a TLS reverse proxy. If an application must be public, open only the ports it needs in UFW and review Docker’s packet-filtering behavior because published ports can bypass ordinary UFW filtering. A VPSLake UFW firewall generator can help draft a starting ruleset.
  • Monitor /var/lib/docker and container logs. Image layers and the default JSON logging driver can consume disk space even when few containers are running.

FAQ

Why use Docker’s repository instead of Ubuntu’s docker.io package?

Ubuntu’s package is maintained separately from Docker’s upstream Engine release cycle. Docker’s repository provides the current Engine package family together with containerd.io, Buildx, and the Compose plugin, which keeps those components aligned.

Does this install Docker Compose?

Yes. The docker-compose-plugin package installs Compose v2, used with docker compose and a space. The older standalone docker-compose command is not needed for new projects.

Do I need Docker Desktop on an Ubuntu VPS?

No. Docker Desktop is aimed at desktop development environments, while Docker Engine is the server daemon used on a headless VPS. This guide installs Engine directly and manages it with systemd.

Where does Docker store its data on Ubuntu?

The default data directory is /var/lib/docker, which contains image layers, containers, networks, and volumes. Account for that directory when sizing disk space, and use deliberate cleanup or log rotation rather than deleting it while containers are running.

Samrat Ghosh
Written by

Samrat Ghosh

Founder & Infrastructure Engineer

Samrat Ghosh is the founder of VPSLake, where he builds and runs the remote desktop and VPS hosting infrastructure the company is built on. He writes hands-on guides about RDP, Windows Server, VPS management and secure remote access - the practical documentation he wishes had…

Previous Article

How to Install Docker on Ubuntu 22.04 (Step-by-Step)

Next Article

MT5 on Mac: Run EAs 24/7 From Your Mac

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Subscribe to our Newsletter

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨