Docker is the standard way to run isolated services on a VPS. This guide installs the latest Docker Engine + docker-compose plugin on Ubuntu 22.04/24.04. Any Hostiger VPS with 2 GB+ RAM handles Docker comfortably.
1. Uninstall any old Docker
apt remove docker docker-engine docker.io containerd runc -y || true
2. Add Docker's official repository
apt update
apt install ca-certificates curl gnupg -y
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
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" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
3. Install Docker Engine + compose plugin
apt update
apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
systemctl enable --now docker
# Verify
docker --version
docker compose version
4. Run as non-root
Add your user to the docker group so you don't need sudo:
usermod -aG docker $USER
newgrp docker
docker run hello-world
5. Your first container
docker run -d --name webtest -p 8080:80 nginx
curl http://localhost:8080
You should see the nginx welcome HTML. Remember to open port 8080 in ufw if you want it public: ufw allow 8080/tcp.
6. docker-compose example
Create compose.yml:
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: change_me
volumes:
- db_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
db_data:
docker compose up -d
docker compose ps
docker compose logs -f web
7. Useful maintenance commands
docker system prune -af # remove unused images, containers, networks
docker container stats # live CPU/RAM per container
docker compose down --volumes # stop stack and delete volumes
journalctl -u docker # engine logs
Security notes
- Never publish the Docker daemon TCP socket (
tcp://0.0.0.0:2375) without TLS — instant remote code exec. - Users in the
dockergroup effectively have root — treat them accordingly. - Pin image versions (
nginx:1.27-alpine) rather than:latestin production.
For heavy container workloads, consider Hostiger High-RAM VPS — Docker plus a database often maxes RAM before CPU.