If you’ve been looking for a self host docker guide, here’s the blunt truth: the hard part isn’t Docker—it’s everything around it (networking, updates, backups, and not exposing your VPS to the internet like an open fridge). This walkthrough focuses on the VPS_HOSTING reality: small servers, public IPs, and the security footguns you actually hit.
1) Choose a VPS: cheap is fine, predictable is better
For self-hosting, your bottleneck is usually operational effort, not raw CPU. Pick a provider with predictable networking and a console you trust. I’ve used hetzner for excellent price/performance and digitalocean for a smoother “it just works” experience when I’m moving fast. Either is perfectly viable for Docker.
Practical baseline specs for most personal stacks:
- 1–2 vCPU / 2–4 GB RAM: enough for reverse proxy + a few services
- 40+ GB SSD: logs and volumes grow faster than you think
- Linux (Ubuntu LTS): boring, documented, and battle-tested
Opinionated take: don’t over-optimize the VPS choice. The biggest wins come from a clean deployment pattern (Compose), a reverse proxy, and backups.
2) Harden the box before you run containers
Your VPS is on a public IP. Assume bots will knock within minutes.
Checklist (do this before exposing apps):
- Create a non-root user, disable password SSH, use keys
- Enable a firewall (UFW is fine)
- Keep the OS updated
At minimum:
- Allow only 22/tcp (SSH) and 80/443 if you’re serving web traffic
- Consider moving SSH off 22 if you want less noise (not security, just quieter logs)
If you’ll terminate TLS, you’ll likely run a reverse proxy (Traefik, Caddy, or Nginx). That means you’re intentionally opening 80/443—everything else should be blocked.
3) Install Docker + Docker Compose (and don’t wing it)
On Ubuntu, install Docker from the official repos (or Docker’s repo if you want newer packages). Then use Docker Compose for repeatable deployments.
Why Compose wins for self-hosting:
- Your stack becomes a file (
compose.yml) you can version control - Upgrades are consistent (
docker compose pull && docker compose up -d) - Volumes are explicit (and therefore back-up-able)
Rule of thumb: one VPS = one Git repo containing Compose files for your services, plus a .env file (not committed) for secrets.
4) A minimal, real deployment: reverse proxy + whoami
Below is a small, actionable setup that proves the end-to-end path: a reverse proxy (Traefik) routes a domain to a test container.
Assumptions:
- DNS A record points
app.yourdomain.comto your VPS IP - Ports 80/443 are open
Create compose.yml:
services:
traefik:
image: traefik:v3.0
command:
- --api.dashboard=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
whoami:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`app.yourdomain.com`)
- traefik.http.routers.whoami.entrypoints=web
Run it:
docker compose up -d- Visit
http://app.yourdomain.com
This isn’t production-ready TLS yet, but it verifies:
- Docker networking works
- Your firewall and ports are correct
- DNS points where you think it points
From here, add TLS (Let’s Encrypt), basic auth for dashboards, and per-service routing.
5) Backups, updates, and “not getting paged at 3am”
Self-hosting is fun until your disk fills up or an update breaks your only copy of data.
Non-negotiables:
- Back up volumes, not containers. Containers are disposable.
- Keep backups off the VPS (object storage, another server, anything).
- Automate updates with intent: schedule them, don’t “latest-tag” yourself into surprise downtime.
Practical patterns:
- Use named volumes for databases.
- Pin image versions (e.g.,
postgres:16.3) instead oflatest. - Add healthchecks where possible.
- Log rotation: Docker logs can silently eat disks.
Networking note: If you use cloudflare in front of your services, you can reduce random internet noise and get easy DNS management. It’s not magic security, but it’s a solid layer for many self-hosted web apps—especially when paired with strict firewall rules.
Final thoughts (and a soft suggestion)
A solid “self host Docker” setup is mostly about discipline: Compose files you can reproduce, a reverse proxy you understand, and backups you actually tested. The provider matters less than the habits.
If you want the simplest path, start on digitalocean for predictable networking and quick iteration, then move to hetzner if cost efficiency becomes a priority. Either way, treat your VPS like production from day one: least privilege, minimal open ports, and boring, repeatable deployments.
Some links in this article are affiliate links. We may earn a commission at no extra cost to you if you make a purchase through them.
Top comments (0)