Docker & Compose on Ubuntu 24.04
Updated Jul 2026
A clean, repeatable way to install Docker Engine and the Compose plugin on Ubuntu 24.04 — the base layer for every self-hosted app on this site.
- A fresh Ubuntu 24.04 server you can SSH into as a sudo user.
- About 20 minutes and a terminal.
- No prior Docker install — we start clean, so remove any distro `docker.io` package first.
Almost every app in our self-hosting guides runs the same way: a docker compose up -d on a small Ubuntu box. This is the clean base layer to set up once, so every later guide is just a compose file away.
Start from a fresh, updated box
After your first SSH login as root, update the system and create a non-root user with sudo — you should not run containers (or anything else) as root day to day.
apt update && apt -y upgrade
adduser deploy && usermod -aG sudo deploy
Log back in as deploy for the rest of this guide.
Install Docker Engine from the official repository
Skip the distro's older docker.io package — install Docker's own repository so you get current Engine and the Compose v2 plugin together.
# official one-line convenience script (inspect it first if you prefer)
curl -fsSL https://get.docker.com | sh
# run docker without sudo
sudo usermod -aG docker $USER && newgrp docker
Verify the install
docker run --rm hello-world
docker compose version
If both succeed, you have Engine plus the Compose plugin. Note it is docker compose (a subcommand) now, not the old docker-compose binary.
Your first stack
Drop a docker-compose.yml in a project folder and bring it up:
mkdir ~/uptime && cd ~/uptime
cat > docker-compose.yml <<'YAML'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
ports: ["3001:3001"]
volumes: ["./data:/app/data"]
restart: unless-stopped
YAML
docker compose up -d
The restart: unless-stopped line is what makes the container survive reboots — Docker's own service is enabled on boot by default, so your stack comes back automatically.
Where to go next
With Docker in place, every app guide on the site is a copy-paste compose file. Next, put HTTPS in front of it — see Automatic HTTPS with Caddy.