Running Docker on your VPS
Install Docker, understand volumes and networking, and avoid the classic data-loss traps.
Docker packages an app and its dependencies so it runs the same everywhere. · source code · Compose
Install
# official convenience script (review it first, as with any script)
curl -fsSL https://get.docker.com | sh
docker --version
docker compose versionThe mental model
Image — a read-only template built from a Dockerfile.
Container — a running instance of an image. Disposable by design.
Volume — persistent storage that outlives containers. Your data lives here.
Network — an isolated virtual network containers attach to.
Compose is how you actually run things
A compose.yaml describes your services. Example:
services:
app:
image: myapp:latest
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080" # loopback only; put a reverse proxy in front
volumes:
- appdata:/data
environment:
- DATABASE_URL=postgresql://...
volumes:
appdata:docker compose up -d # start
docker compose logs -f app # follow logs
docker compose pull && docker compose up -d # update
docker compose down # stop (volumes preserved)The traps that eat data
docker compose down -vdeletes volumes. That flag removes your data. Never run it on anything you care about.docker system prune -aremoves unused images;--volumesalso removes volumes. Plainprune(images only) is usually safe; be careful with the volume flag.Data in the container's filesystem vanishes on recreation. Always mount a volume for anything persistent.
Binding to
0.0.0.0. Map ports to127.0.0.1and proxy through Nginx/Caddy so a container never opens a public port by accident.
Networking
Containers on the same Compose network reach each other by service name — postgres, redis — not by IP. That is the whole point of the network abstraction.
Security
Do not run containers as root where avoidable (
user:in compose).Pin image tags (
postgres:16.4) rather than:latest, so an update is a decision, not a surprise.Rebuild on a schedule to pick up base-image security patches.
Container escape is real: keep Docker daemon access equal to root access in your threat model.
Disk hygiene
Docker accumulates images, build cache and logs:
docker system df # what is using space
docker image prune -f # remove dangling images
docker builder prune -f # clear build cacheRelated reading