Docker VPS Setup Guide 2025: Deploy Containers on UK VPS Hosting
Docker has become the standard way to deploy and run applications in production. Whether you're a solo developer running side projects or a growing UK startup scaling your SaaS, running Docker on a UK VPS gives you the isolation of containers with the performance of dedicated hardware — all at a fraction of cloud costs.
In this guide, we'll walk through setting up Docker on a UK VPS for production workloads. We'll cover installation, Docker Compose, networking, security hardening, monitoring, and backup strategies.
📋 What You'll Learn
1. Prerequisites & Choosing Your VPS
Before we start, you need a UK VPS with the following minimum specifications for Docker workloads:
- CPU: 2+ cores (4+ recommended for production)
- RAM: 4GB minimum (8GB+ for multiple containers)
- Storage: NVMe SSD (50GB+ for container images and data)
- OS: Ubuntu 24.04 LTS (our recommended host OS)
- Kernel: Linux kernel 5.x+ with cgroups v2 support
Docker runs natively on Linux and requires a host with cgroups and namespace support — both of which are available on modern KVM-based VPS platforms like Hostingowy.
2. Installing Docker Engine on Ubuntu 24.04
Connect to your VPS via SSH and follow these steps to install Docker Engine:
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up the Docker repository
echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Verify installation
sudo docker run hello-world
# Add your user to the docker group (avoids sudo)
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect
3. Docker Compose for Multi-Container Apps
Docker Compose lets you define and run multi-container applications with a single YAML file. Here's a production-ready example for a typical web application stack:
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- certbot-data:/var/www/certbot
depends_on:
- app
networks:
- frontend
- backend
app:
build: ./app
env_file: .env
volumes:
- static-data:/app/static
- media-data:/app/media
expose:
- "8000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- backend
db:
image: postgres:16-alpine
volumes:
- postgres-data:/var/lib/postgresql/data
env_file: .env
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
command: redis-server --appendonly yes
networks:
- backend
certbot:
image: certbot/certbot
volumes:
- certbot-data:/var/www/certbot
- ./ssl:/etc/letsencrypt
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
volumes:
postgres-data:
redis-data:
static-data:
media-data:
certbot-data:
networks:
frontend:
backend:
Deploy with a single command:
docker compose up -d
4. Container Networking & Reverse Proxy
For production deployments, you'll want a reverse proxy (Nginx or Caddy) handling TLS termination and routing traffic to your containers. Here's a recommended network architecture:
# nginx.conf — Reverse proxy configuration
events {
worker_connections 1024;
}
http {
upstream app_backend {
server app:8000;
}
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://app_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ {
alias /app/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /app/media/;
expires 7d;
}
}
}
5. Securing Docker in Production
Security is paramount when running containers on a UK VPS. Follow these hardening steps:
5.1 Docker Daemon Security
# /etc/docker/daemon.json
{
"icc": false,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"userland-proxy": false,
"iptables": true,
"live-restore": true,
"no-new-privileges": true
}
5.2 Run Containers with Least Privilege
# Never run containers as root
docker run --user 1000:1000 \
--read-only \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
myapp:latest
5.3 Resource Limits
# Prevent noisy neighbors
docker run --memory="512m" --cpus="0.5" --pids-limit=100 myapp
5.4 Regular Security Updates
# Update all running containers (weekly cron)
docker system prune -af # Remove unused images/containers
docker pull myapp:latest
docker compose up -d --pull always
6. Monitoring Docker Containers
Monitor your Docker hosts with the open-source Prometheus stack:
Prometheus + cAdvisor Setup
# docker-compose.monitoring.yml
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
privileged: false
devices:
- /dev/kmsg
restart: unless-stopped
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
restart: unless-stopped
Key metrics to watch:
- Container CPU/memory usage — cAdvisor metrics
- Disk I/O per container — Detect noisy neighbors
- Network traffic — Per-container bandwidth
- Docker daemon health — Engine uptime and errors
7. Backup Strategies for Container Data
Container data requires special backup consideration since volumes are ephemeral by design:
#!/bin/bash
# docker-backup.sh — Weekly backup script
BACKUP_DIR="/backups/containers"
DATE=$(date +%Y-%m-%d)
# Backup PostgreSQL database
docker exec db pg_dump -U myuser mydb > \
${BACKUP_DIR}/db-${DATE}.sql
# Backup Docker volumes (using a helper container)
docker run --rm \
-v postgres-data:/source:ro \
-v ${BACKUP_DIR}:/backup \
alpine tar czf /backup/postgres-data-${DATE}.tar.gz -C /source .
# Compress and encrypt
gpg --encrypt --recipient admin@hostingowy.com \
${BACKUP_DIR}/db-${DATE}.sql
# Sync to offsite backup
rsync -avz ${BACKUP_DIR}/ backup@offsite:/backups/
# Retention: keep 30 daily, 12 monthly
find ${BACKUP_DIR} -name "*.sql" -mtime +30 -delete
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +30 -delete
8. Production Deployment Checklist
Before going live, verify each item:
- ☐ TLS certificates — Auto-renewing with Certbot/LetsEncrypt
- ☐ Health checks — Configured in docker-compose.yml
- ☐ Resource limits — CPU/memory set per container
- ☐ Log rotation — Docker daemon log limits configured
- ☐ Monitoring — Prometheus/cAdvisor tracking key metrics
- ☐ Backups — Automated daily database + volume backups
- ☐ Security scanning — Docker Scout or Trivy for image CVEs
- ☐ Firewall — UFW blocking all ports except 80, 443, SSH
- ☐ fail2ban — SSH and web app brute-force protection
- ☐ Docker updates — Weekly unattended-upgrades for Docker packages
Ready to Deploy Docker on UK VPS Hosting?
Our KVM-based VPS plans give you full root access, NVMe storage, and European data centre (Poland) locations — perfect for Docker workloads.
Start Free Trial →