How to Secure a VPS That Runs Docker Containers
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
Controls you can verify beat controls you assume are working.
Security coverage here is scoped to systems a small team actually operates: a rented Linux host, containers, a database, a CI pipeline and a CDN in front. No threat modelling frameworks, no compliance checklists.
The organising principle is verification. A firewall rule you have not tested from outside the host is a belief. A backup you have not restored is a hypothesis. A permission you assume is narrow is worth checking, because the gap between intended and actual configuration is where nearly every self-hosted compromise lives.
The single most under-appreciated issue in this stack is that Docker manipulates
iptables directly. Its rules are evaluated before the ones UFW manages, which
means a container published with -p 5432:5432 is on the public internet even
though the firewall shows a default-deny policy. People discover this from a
compromised database, not from a scan.
After that, in rough order of value: key-only SSH with root login disabled; secrets in files with restrictive permissions rather than in images or workflow YAML; application database roles that cannot alter their own schema; and container settings that drop capabilities and block privilege escalation.
The supply chain deserves its own attention. A pipeline runs with production credentials, third-party actions run with access to those credentials, and a mutable version tag can point at new code tomorrow. Pinning to commit hashes and scoping tokens per job costs nothing and removes an entire category of risk.
Every article here includes the command that proves the control works, not just the command that configures it.
Start here
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
A reading order that builds Security knowledge in the sequence it is actually needed.
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
Failure modes that come up repeatedly with Security, and where each one is solved.
Keep the listener off the public internet, get pg_hba.conf right, require TLS for remote connections, and give the application a role that cannot drop your tables — on PostgreSQL 17 and Ubuntu 24.04.
A Meilisearch deployment that survives a real workload — master key handling, scoped API keys, the index settings you must set before loading data, snapshots, and what its memory usage actually means.
Expose Docker services through Cloudflare with no inbound ports open — cloudflared plus Traefik, the forwarded-header setting that trips people up, and how to verify the firewall is closed.
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
Create the A record, pick the right proxy status, set the SSL mode to Full (strict) and lock the origin so only Cloudflare can reach it — plus what errors 521, 522, 525 and 526 actually mean.
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
Key-only SSH authentication with root login disabled, followed immediately by checking whether published container ports are bypassing the firewall. Those two cover the overwhelming majority of opportunistic compromise.
Scan from a different machine. Checking `ss -tlnp` on the host tells you what is listening, which is a different question from what the internet can reach.
It reduces log noise from automated scanners and nothing else. Treat it as housekeeping, not as a control, and do not let it substitute for disabling password authentication.