Docker packages an app and everything it needs into a container that runs the same anywhere — the cleanest way to self-host services on a VPS. The one catch on Ubuntu and Debian is that the version in the distro's own repository is often old and ships without the modern Compose plugin. Install from Docker's official repository instead. Here's the whole process.
1. Set up Docker's official repository (Ubuntu)
sudo apt update
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
2. Install Docker Engine and Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
3. Confirm it's running and enabled on boot
sudo systemctl enable --now docker
sudo docker run --rm hello-world
The hello-world container downloads, prints a success message and exits — proof the engine works.
4. (Optional) Run Docker without sudo
sudo usermod -aG docker $USER
# log out and back in for the group to take effect
Only do this for a user you trust — docker-group access is effectively root on the host.
A quick real container
docker run -d --restart unless-stopped -p 8080:80 --name web nginx
# visit http://YOUR.SERVER.IP:8080
--restart unless-stopped is what makes the container come back after a reboot.
Honest cautions
- Use the official repo for a current version; the distro
docker.iopackage lags and lacks the Compose plugin. - Open only the ports you publish. A container's
-p 8080:80exposes 8080 — pair Docker with a UFW firewall. - Size the box to the containers, not to Docker itself, which is light.
Next steps
With Docker installed you can self-host almost anything. See self-hosting multiple services behind one IP, or concrete Docker builds like a RustDesk remote-desktop server and Uptime Kuma monitoring. To put a domain and HTTPS in front, see how to set up an nginx reverse proxy.
Comments
No comments yet. Be the first.