Most of what people call "container security" is a short list of defaults you can set in an afternoon. The exotic tooling — admission controllers, runtime sensors, policy engines — matters at scale, but it's the polish, not the foundation. What actually moves the needle is a handful of flags and one or two Dockerfile lines, ranked here by leverage: highest-impact, lowest-effort first.
I'm going to skip the compliance framing. None of this is about passing an audit. It's about making the difference between "an attacker got code execution in the container" and "an attacker got code execution on the host" as wide as I can with defaults.
Don't run as root
This is the single highest-leverage change, so it goes first. By default a process in a container runs as UID 0. It's namespaced root, not host root — but it's still root inside, and the day someone chains a container escape (a kernel bug, a misconfigured mount, a runc CVE) with root-in-container, that's the bad day. Root inside plus an escape is root on the box. A non-root UID turns the same escape into a much smaller problem.
Set it in the Dockerfile. Create a real user, don't just USER 1000 on top of a root-owned filesystem:






