Install Docker on Ubuntu (Hetzner Server Setup)
Today I decided to document the Docker installation steps I repeat every time I spin up a new Hetzner server. I deploy projects the old school way: a bare Ubuntu VPS, Docker, and docker compose. No Kubernetes, no managed container services. It keeps costs low and the setup predictable.
The problem is I end up Googling “install docker ubuntu” every single time. Not anymore.
The Full Installation Script
This uses Docker’s official APT repository (not the docker.io package from Ubuntu’s default repos, which is often outdated).
#!/bin/bash
set -e
echo "==> Updating packages and installing dependencies..."
sudo apt update
sudo apt install -y ca-certificates curl
echo "==> Adding Docker GPG key..."
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 "==> Adding Docker APT repository..."
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
echo "==> Installing Docker Engine..."
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
echo "==> Enabling and starting Docker..."
sudo systemctl enable docker
sudo systemctl start docker
echo "==> Adding current user to docker group..."
sudo usermod -aG docker $USER
echo "==> Verifying installation..."
docker --version
echo ""
echo "Docker installed successfully!"
echo "Log out and back in (or run 'newgrp docker') to use Docker without sudo."
What Gets Installed
| Package | Purpose |
|---|---|
docker-ce | Docker Engine (Community Edition) |
docker-ce-cli | CLI tools for managing containers |
containerd.io | Container runtime |
docker-buildx-plugin | Extended build capabilities with BuildKit |
docker-compose-plugin | docker compose (v2, replaces standalone docker-compose) |
How to Use
Option A: Save and run locally
nano install-docker.sh
# paste the script, save with Ctrl+X
chmod +x install-docker.sh
./install-docker.sh
Option B: Run from a remote URL (if you host the script in a repo)
curl -fsSL https://your-repo.com/install-docker.sh | bash
Post-Install: Apply Group Change
After the script completes, the docker group membership won’t take effect until you start a new session. Apply it immediately:
newgrp docker
Then verify everything works:
docker run hello-world
docker compose version
What I Learned
- Always use Docker’s official APT repository. The
docker.iopackage in Ubuntu’s default repos lags behind significantly - The
docker-compose-plugingives youdocker compose(with a space) as a native subcommand. No need to install standalonedocker-composeseparately anymore usermod -aG docker $USERsaves you from typingsudobefore every Docker command, but requires a re-login to take effectnewgrp dockeris the shortcut to avoid a full logout/login cycle- Keeping this as a single script means a fresh Hetzner server goes from bare Ubuntu to Docker-ready in under 60 seconds
Deploying to Hetzner or similar VPS providers? I’d love to hear about your setup. Reach out on LinkedIn.