OrbitHost
Guides

Install Docker on Ubuntu 24.04 VPS (Engine + Compose)

Step-by-step Docker Engine and Compose install on Ubuntu 24.04 LTS. Official apt repo, non-root user, firewall notes, and a smoke-test compose stack for EU VPS.

By Alex Rivera · Infrastructure Engineer9 min read
Author
Alex Rivera
Infrastructure Engineer

Alex designs and hardens EU VPS fleets in Frankfurt and Amsterdam. He spends most days on Docker, KVM networking, NVMe layouts, and keeping Ubuntu 24.04 boxes boringly reliable for production workloads.

What you need before installing

This guide installs Docker Engine and the Compose plugin on Ubuntu 24.04 LTS. It assumes a fresh KVM VPS with root or sudo access, outbound HTTPS, and a public IPv4. Nested Docker on OpenVZ is unreliable; stick to KVM.

On OrbitHost, pick a Frankfurt or Amsterdam Ryzen NVMe plan if your users are in Europe. A Nano plan is fine for learning; use Core or higher once you add databases, CI runners, or multiple Compose services.

Update the system first so apt metadata and CA certificates are current. Reboot if the kernel bumped — Docker talks to the running kernel via containerd and cgroups.

sudo apt update && sudo apt upgrade -y
sudo reboot  # only if a new kernel was installed

Install prerequisites and Docker’s GPG key

Docker publishes signed packages. You add their GPG keyring, then an apt source that matches your Ubuntu release (`noble` for 24.04). Skip random one-liner install scripts when you want a reproducible server.

The packages you want are `docker-ce`, `docker-ce-cli`, `containerd.io`, `docker-buildx-plugin`, and `docker-compose-plugin`. That set covers Engine, CLI, Buildx, and Compose v2.

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

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

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

Enable Docker and verify the install

After install, enable the service so it survives reboot. `docker run hello-world` pulls a tiny image and exits — enough to prove registry access, storage drivers, and cgroup mounting work.

Check versions so you know what landed: Engine, Compose plugin, and Buildx. If hello-world fails with TLS or DNS errors, fix outbound networking before debugging Docker itself.

  • systemctl enable --now docker
  • docker version / docker compose version
  • docker run --rm hello-world
sudo systemctl enable --now docker
sudo docker run --rm hello-world
docker --version
docker compose version

Run Docker as a non-root user

Adding your deploy user to the `docker` group avoids `sudo` on every command. Log out and back in (or use `newgrp docker`) so the group membership applies.

Treat docker group membership like root: anyone who can talk to the Docker socket can mount the host filesystem. Keep SSH keys tight and avoid shared passwords on production VPS boxes.

sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-world

Firewall and published ports

If UFW is enabled, allow SSH first so you do not lock yourself out. Then open only what you publish. Docker’s default bridge publishes container ports on the host; a public PostgreSQL on `:5432` is a common mistake.

For reverse-proxied apps, publish 80/443 on the proxy container (Caddy, Traefik, nginx) and keep app ports on the internal Compose network. That pattern scales cleanly into Coolify or Dokploy later.

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status

Smoke-test with Compose

Create a minimal Compose file that serves a static page. If this comes up, your Engine + Compose plugin path is healthy and you can move on to real stacks.

Put project files under `/opt` or `/srv` with ownership for your deploy user. Avoid scattering compose projects in `/root` if multiple people manage the VPS.

# /opt/hello/compose.yaml
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    restart: unless-stopped

Useful day-two commands

Learn a short ops loop: `docker ps`, `docker compose logs -f`, `docker system df`, and occasional `docker system prune` after you understand what prune deletes. Never prune volumes blindly on production.

Pin image tags in Compose (`nginx:1.27-alpine`) instead of floating `latest` for anything you care about. Combine that habit with backups of named volumes and you already outrank most hobby setups.

When you outgrow manual Compose, OrbitHost’s Docker-oriented VPS pages and guides for Coolify/Dokploy cover git-push deploys on the same Ubuntu base.

  • docker ps -a — containers including stopped ones
  • docker compose logs -f service — live logs
  • docker system df — disk use by images/volumes
  • journalctl -u docker -e — daemon issues

Sizing tips for EU workloads

NVMe I/O matters for image pulls and database volumes. Ryzen cores help multi-container builds. If you compile inside containers often, prefer 4+ vCPU so BuildKit does not starve your app processes.

Place the VPS near your users: Frankfurt for DE/AT/CH, Amsterdam for NL/BE/UK edge. Latency to registries (Docker Hub, GHCR) is usually fine from both; your end-user RTT is the bigger product decision.

FAQ

Should I install Docker from Ubuntu’s default apt packages?

Prefer Docker’s official apt repository. The Ubuntu universe packages lag and sometimes split Engine/CLI differently. The official repo keeps docker-ce, containerd, and the Compose plugin on a predictable upgrade path.

How much RAM do I need for Docker on a VPS?

A single small service can run on 1–2 GB. For Compose stacks with databases and reverse proxies, start at 4 GB. OrbitHost Core plans in Frankfurt or Amsterdam are a practical baseline for most side projects.

Do I need to disable UFW before installing Docker?

No. Install first, then open only the ports you expose (80/443 for web, plus any app ports). Docker publishes containers by rewriting iptables; keep UFW rules intentional and avoid publishing databases to 0.0.0.0.

What is the difference between docker-compose and the Compose plugin?

The modern path is `docker compose` (plugin). The old standalone `docker-compose` binary still exists in many tutorials but is no longer required on Ubuntu 24.04 with Docker’s official packages.

Can I run Docker on OpenVZ or only KVM?

Use KVM. Nested container runtimes need a real kernel and cgroup support. OrbitHost cloud VPS is KVM with NVMe — suitable for Docker Engine and Compose.

Ready to Launch?

Create your server today.