How to Set Up Docker on Ubuntu 24.04

by David Park
How to Set Up Docker on Ubuntu 24.04

By the end of this guide you will have Docker Engine and the Docker CLI installed on Ubuntu 24.04, configured to run without sudo, and verified with a live container. You will also have the daemon set to start on boot via systemd. No Docker Desktop, no Snap package — just the upstream Docker Engine that actually works in production.

Prerequisites

  • A fresh or existing Ubuntu 24.04 LTS server (amd64 or arm64)
  • A non-root user with sudo privileges
  • Outbound internet access on port 443
  • At least 2 GB of disk space free on /var

Step 1 — Remove Conflicting Packages

Ubuntu 24.04 ships with docker.io and related shims that conflict with the upstream Docker Engine. Remove them first.

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

This command uninstalls every conflicting package. apt-get will print "Package X is not installed" for anything already absent — that is expected.


Step 2 — Update the Package Index and Install Dependencies

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

ca-certificates and curl are needed to fetch the Docker GPG key over HTTPS. gnupg is required to import and verify it.


Step 3 — Add Docker's Official GPG Key

  1. Create the keyring directory:
sudo install -m 0755 -d /etc/apt/keyrings
  1. Download and store the key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  1. Set correct permissions so apt can read the key:
sudo chmod a+r /etc/apt/keyrings/docker.gpg

These three commands create a dedicated keyring file for Docker at /etc/apt/keyrings/docker.gpg with world-readable permissions.


Step 4 — Add the Docker APT Repository

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
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 a single-line APT source entry to /etc/apt/sources.list.d/docker.list. The $(dpkg --print-architecture) substitution pins the repo to your CPU architecture (amd64 or arm64). The $VERSION_CODENAME substitution resolves to noble on Ubuntu 24.04.

Verify the file was written correctly:

cat /etc/apt/sources.list.d/docker.list

Expected output:

deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable

Step 5 — Install Docker Engine

  1. Refresh the package index to pick up the new repo:
sudo apt-get update
  1. Install Docker Engine, the CLI, containerd, and the Compose plugin:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Package Purpose
docker-ce Docker Engine daemon
docker-ce-cli docker command-line client
containerd.io Container runtime
docker-buildx-plugin Extended build capabilities
docker-compose-plugin docker compose subcommand

This is the full production stack. Skipping any of these packages will leave you with a partial install.


Step 6 — Enable and Start the Docker Daemon

sudo systemctl enable --now docker

The --now flag both enables the docker unit for automatic start on boot and starts it immediately in a single command. The systemd unit name is docker.service.

Check the daemon status:

sudo systemctl status docker

Expected output (truncated):

● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since ...

If the status shows active (running), the daemon is up.


Step 7 — Run Docker Without sudo

By default, the Docker socket is owned by the docker group. Add your user to that group so you can run docker commands without sudo.

  1. Add your current user to the docker group:
sudo usermod -aG docker $USER
  1. Apply the new group membership without logging out:
newgrp docker

newgrp docker starts a new shell session with the docker group active. In automated provisioning scripts, prefer logging out and back in instead.

Security note: Any user in the docker group has effective root access to the host via volume mounts. Only add trusted users.


Step 8 — Configure the Docker Daemon (Optional but Recommended)

Create /etc/docker/daemon.json to set a log rotation policy and a sane storage driver. Without log rotation, container logs will fill your disk on a busy server.

sudo tee /etc/docker/daemon.json > /dev/null <<EOF
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2"
}
EOF

Reload the daemon to apply the configuration:

sudo systemctl reload docker

This caps each container's log at 10 MB with 3 rotated files — 30 MB maximum per container. overlay2 is the correct storage driver for Ubuntu 24.04 with ext4 or XFS.


Verify It Works

Run the official smoke-test image:

docker run --rm hello-world

Expected output:

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

Verify the Docker Compose plugin is available:

docker compose version

Expected output:

Docker Compose version v2.27.0

(The exact version number will vary; any v2.x output confirms the plugin is installed.)

Verify the daemon configuration was applied:

docker info | grep -E 'Storage Driver|Logging Driver'

Expected output:

 Storage Driver: overlay2
 Logging Driver: json-file

Troubleshooting

docker: permission denied while trying to connect to the Docker daemon socket Your user is not yet in the docker group, or the group change has not taken effect. Run newgrp docker or log out and back in. Confirm with groups — you should see docker in the list.

**apt-get update fails with NO_PUBKEY or GPG error** The key at /etc/apt/keyrings/docker.gpg` was not written correctly. Delete it and repeat Step 3:

sudo rm /etc/apt/keyrings/docker.gpg

Then re-run the curl | gpg command from Step 3.

docker.service fails to start — containerd socket not found` containerd may not have started. Run:

sudo systemctl status containerd
sudo systemctl start containerd
sudo systemctl restart docker

overlay2 not listed in docker info Your kernel may lack the overlay module. Load it manually and verify:

sudo modprobe overlay
lsmod | grep overlay

If the module is absent, upgrade the kernel: sudo apt-get install -y linux-generic.

hello-world image pull times out Check outbound connectivity: curl -I https://registry-1.docker.io. If you are behind a proxy, configure /etc/systemd/system/docker.service.d/http-proxy.conf with your proxy settings and reload the daemon.

daemon.json causes the daemon to fail on reload Validate the JSON before applying:

python3 -m json.tool /etc/docker/daemon.json

A syntax error in daemon.json will prevent the daemon from starting. Fix the file and run sudo systemctl restart docker.


Next Steps

With Docker running on Ubuntu 24.04, you are ready to:

  • Deploy a container in production — use docker run -d --restart=unless-stopped to keep services alive across reboots.
  • Set up Docker Compose projects — create a compose.yml and manage multi-container stacks with docker compose up -d.
  • Harden the daemon — enable user namespaces (userns-remap) in daemon.json to isolate container root from host root.
  • Set up a private registry — run registry:2 as a container to cache images locally and cut egress costs on Hetzner or any metered VPS.
  • Monitor disk usage — schedule docker system prune -f weekly via cron to reclaim space from dangling images and stopped containers.

This setup costs nothing beyond your existing VPS and runs reliably on a $4/month Hetzner CAX11 ARM instance.