A Docker Security Checklist for Production Hosts
A production-ready Docker checklist: hardened host, minimal pinned images, non-root read-only runtime, capability drops, limits, and clean network hygiene.
Netbay Cloud Team
Netbay Engineering
On this page
Docker does not make a host insecure by default — it just leaves every default on, and the defaults were chosen for convenience, not for a public-facing server. The practical question is which knobs to turn before trusting a production box, and in what order, because a checklist you cannot apply is a wish. This guide is that checklist: host foundation, image policy, runtime hardening, resource limits, network hygiene, and operations — each item concrete enough to verify in a single command, and complete enough to stand up to a review.
Layer One: The Host Foundation
A hardened Docker stack starts on a boring host. Use a current LTS distribution, enable automatic security updates, and keep SSH hardened with key-only login. The firewall should close everything except the ports you actually publish, and the Docker daemon belongs on the local socket only — never expose 2375 or 2376 to the network, because an unauthenticated daemon socket is root on the box. Verify with the obvious commands: the byte-cheap checks that prove the foundation holds.
ufw status verbose
ss -tlnp | grep -E '2375|2376' # nothing listening here
docker context ls
apt list --upgradable | headThe context line confirms you are talking to the local daemon and not some accidentally discovered remote socket. If 2375 or 2376 appears in ss output, close it before evaluating a single container — that socket is the whole farm's front door.
Layer Two: Image Policy
Image hygiene is a policy before it is a pipeline. Pin images to explicit versions and digests; never deploy latest, because two hosts that pull at different times run different software with the same name. Run a scanner on the registry or in CI so a vulnerable base is caught before it is deployed, and prefer slim images that genuinely lack the packages a scanner would flag.
FROM debian:bookworm-slim@sha256:9f1f1e1f5a9e9d9b3e4d3c2b1a0f0e0d0c0b0a09080706050403020100
# or at minimum: FROM postgres:16-alpine
LABEL org.opencontainers.image.revision="7c9f2a1"The digest (shown shortened here; a real one is longer and opaque, which is the point) makes the image content provably identical everywhere. A pinned digest plus a scanned registry turns "which version is running" from a question into a quoted fact.
Layer Three: Runtime Hardening
Every container that faces untrusted traffic should run with the full hardening set: non-root user, read-only rootfs, all capabilities dropped, no-new-privileges, and a seccomp profile. These are the four paragraph-one settings this series keeps returning to because they are the difference between "compromised process" and "compromised host".
name: api
services:
web:
image: my-api:2.4
read_only: true
tmpfs:
- /tmp:size=64m
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
user: "10001:10001"
restart: unless-stoppedPrefer running without --privileged and without host-mode networking unless a genuine requirement forces them. Docker's default seccomp profile is active out of the box; knowing it is there, and never disabling it per-container without review, is the discipline that keeps the profile meaningful.
Layer Four: Resource Limits
A container that can exhaust host memory or saturate four CPUs is a fault-isolation hole. Give every service explicit ceilings — memory, CPU, and process count — so a leak inside one container degrades that container instead of the whole host.
name: api
services:
worker:
image: my-worker:1.1
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
pids_limit: 256
read_only: true
cap_drop:
- ALL
security_opt:
- no-new-privileges:truepids_limit is the one that most teams skip, and it is the guard against fork bombs inside a container — a runaway that would otherwise grind the host scheduler to a standstill. Memory limits without swap discipline can still write pressure through the host; set swap limits on the host level and keep the container memory well-defined.
Layer Five: Network Hygiene
One custom bridge network per trust tier, published ports only, and host-mode reserved for the few containers with a real reason. A database attached to the same network as the public web tier is one exploit away from being directly reachable; a database on its own internal network requires an explicit act to expose. The checks are the same commands from the networking post in this series: docker network inspect shows membership, docker port shows exposure.
docker network ls
docker network inspect appnet
docker port web
docker ps --filter "network=appnet"Every printed row is either a name you intended or a finding. If the reverse proxy's network contains a database container, that is a config choice you should be forced to explain in a review.
Layer Six: Operations Discipline
Security checklists rot without operations: prune, update, rotate, back up.
docker image prune -af
docker builder prune -af
docker container prune -f
docker system df
docker volume lsWeekly pruning removes dangling images and build cache; regular base-image pulls and rebuilds close the update gap that scanners expose; secrets rotate on a schedule instead of on incident (the worst time to migrate is during an ongoing breach); and volumes get their own backup story separate from the host disk. None of these commands is glamorous, and all four are what keep a checklist that was true in June still true in August.
Takeaway
A production Docker host is the sum of its defaults being deliberately overridden: a patched and firewalled host, pinned and scanned images, non-root read-only containers with capabilities dropped, explicit resource ceilings, segmented networks, and a pruning and rotation rhythm. Every item above is verifiable in one command that a reviewer can run, and together they describe a host where a single compromised process has nowhere convenient to go. On a Netbay VPS with full root and Docker-ready SSD storage, the entire checklist is yours to apply from the first boot onward — start at netbayhosts.in.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance