Container and Docker runtime security protects the software running inside a container — the base image, the live process, and the host kernel it shares — from compromise. It is a distinct problem from Kubernetes orchestration security, which governs clusters, RBAC, and network policy and deserves its own guide. Most container breaches trace back to four repeatable causes: a vulnerable base image pulled from a public registry, a container running as root with no capability limits, an exposed Docker daemon socket that hands out root-equivalent access to the host, and no runtime detection once the workload is actually live. This guide walks through each risk and ends with a practical hardening checklist for Indian DevOps teams shipping containers to production.
Why Container Security Is a Different Problem From Kubernetes Hardening
Kubernetes hardening deals with the orchestration layer — who can create pods, which services can talk to each other, how secrets are mounted across a cluster. Container and Docker runtime security deals with the layer underneath: what code shipped inside the image, what privileges the process gets at boot, and what happens if that process is compromised. A perfectly locked-down Kubernetes RBAC policy does nothing to stop a container running as root from walking straight out to the host if the underlying image has an unpatched kernel-adjacent library or the daemon socket is mounted into the pod. Teams that treat "we hardened Kubernetes" as equivalent to "we hardened our containers" routinely miss this layer, and it is the layer attackers hit first because it is closer to the actual code.
For Indian SMBs and mid-market SaaS companies running Docker in production — whether on bare EC2, ECS, or a self-managed cluster — this distinction matters because container image and runtime issues are usually cheaper to fix and more commonly exploited than orchestration misconfigurations.
Vulnerable Base Images: The Root Cause of Most Container Compromises
Every container inherits the vulnerabilities of its base image. A FROM node:18 or FROM python:3.9 pulled without pinning drags in whatever OS packages, language runtime, and system libraries were bundled at build time — often months or years out of date by the time the image reaches production. Public registries make this worse: images are frequently built from other unverified public images, so a single unpatched dependency can propagate across hundreds of downstream projects without anyone noticing.
The fix is not glamorous but it works: pin base image versions and digests instead of floating tags like latest, prefer minimal images (distroless, alpine, or slim variants) that carry a smaller attack surface, and rebuild on a schedule so patched CVEs actually reach production rather than sitting in a Dockerfile that nobody revisits.
latest is not a version — it is a moving target. A build that passed security review last month can silently pull a different, vulnerable image today if the tag has been reassigned upstream. Always pin to a specific digest for anything deployed to production.Running Containers as Root: The Most Common Misconfiguration
By default, most Docker images run as the root user inside the container unless the Dockerfile explicitly sets a USER directive. Inside the container this feels harmless — it is still "just a container" — but if an attacker achieves code execution through an application vulnerability, running as root means they inherit root privileges for every subsequent step: writing to mounted volumes, modifying binaries, and, if any container-breakout primitive is available (a kernel bug, a misconfigured capability, or a mounted host path), escalating straight to the host as root.
The fix is a single line in most Dockerfiles: create a non-root user, USER appuser, and drop Linux capabilities you do not need with --cap-drop=ALL plus only the specific capabilities the process requires. Combine this with --security-opt=no-new-privileges to stop the process from re-acquiring privileges it dropped. NIST's Application Container Security Guide (SP 800-190) identifies containers running as root and unrestricted capabilities among the most common container-specific risks, which is why both controls belong at the top of any hardening checklist.
Know your vulnerabilities before attackers do
Run a free VAPT scan — takes 5 minutes, no signup required.
Book Your Free ScanMissing Resource Limits: Denial of Service From Within
A container started without CPU and memory limits can consume the entire host's resources — either through a genuine bug (a memory leak, a runaway loop) or through deliberate abuse (a cryptominer dropped via a compromised dependency, or an attacker using your compute for their own workload). On shared hosts running multiple containers, one unbounded container can starve every other service on the box, turning what should be an isolated failure into a full outage.
Setting --memory, --memory-swap, and --cpus (or their Compose/ECS task-definition equivalents) is a five-minute fix that converts a potential host-wide outage into a single contained failure. It is also one of the most commonly skipped controls because containers "work fine" without limits in development, where resource contention rarely shows up until production traffic or an active compromise exposes the gap.
The Exposed Docker Daemon Socket: A Root-Equivalent Backdoor
The Docker daemon socket (/var/run/docker.sock) is the API endpoint that controls the entire Docker engine — creating containers, mounting host paths, and running commands as root on the host. Mounting this socket into a container, a common pattern for CI runners, monitoring agents, or "Docker-in-Docker" tooling, is functionally equivalent to giving that container root access to the host itself. Any code running inside that container — including a compromised dependency — can use the socket to spin up a new privileged container with the entire host filesystem mounted, and walk out.
This is the single most consequential misconfiguration covered in this guide, because it collapses "container compromise" and "host compromise" into the same event.
/var/run/docker.sock mounted, treat it as running with full root on the host — because it effectively is. Never mount the socket into an application container. If a CI or monitoring tool genuinely needs Docker API access, isolate it on a dedicated host with no other workloads, and gate access behind authentication rather than an open bind mount.Image Scanning With Trivy and Grype: Shifting Left
Static image scanning catches known vulnerabilities before a container ever runs. Trivy and Grype are the two most widely used open-source scanners: both walk an image layer by layer, match installed packages against public vulnerability databases, and flag known CVEs by severity. The value is in when they run — a scan that only happens after deployment is a compliance checkbox, not a control. Wiring Trivy or Grype into the CI pipeline so a build fails on new critical or high-severity findings turns image scanning into an actual gate rather than a report nobody reads.
Scanning alone will not fix a vulnerable image; it only tells you it is vulnerable. Pair it with a policy: critical findings block the build, high findings require a documented exception with an owner and a deadline, and base images are rebuilt on a fixed cadence so patches that land upstream actually reach your registry. According to the Docker security documentation, combining automated scanning with minimal, regularly rebuilt base images meaningfully reduces the exploitable surface a running container exposes.
Runtime Threat Detection: Catching What Scanning Misses
Image scanning tells you what could go wrong before deployment. Runtime detection tells you what is actually going wrong in a live container — a process spawning a reverse shell, a container reading files outside its expected working directory, an unexpected outbound connection to a new IP. Because scanning only sees what shipped in the image, it cannot catch a compromise introduced after deployment: a dependency confusion attack, a stolen credential used from inside the container, or a zero-day exploited against a package that had no known CVE at build time.
Runtime tools built on Linux kernel tracing (eBPF-based agents, seccomp profiles, and AppArmor/SELinux policies) watch actual syscalls and process behavior rather than static file contents, which is what lets them flag anomalies that no scanner would have caught. For most Indian teams without a dedicated platform security function, the practical starting point is enabling the default seccomp and AppArmor profiles Docker already ships with — most production incidents involve teams that had disabled these defaults for convenience and never revisited the decision.
A Practical Container Hardening Checklist for Indian Dev Teams
| Control | Why It Matters | Typical Effort |
|---|---|---|
Pin base images to a digest, not latest | Stops silent drift to a newer, unvetted image | Minutes per Dockerfile |
Add USER directive, drop unused capabilities | Limits blast radius if the process is compromised | Minutes per Dockerfile |
| Set CPU and memory limits on every container | Prevents one container from starving the host | Minutes per service |
Never mount /var/run/docker.sock into app containers | Removes a root-equivalent host backdoor | Architecture review |
| Run Trivy or Grype in CI, fail build on critical CVEs | Catches known vulnerabilities before deploy | Half a day to wire up |
| Rebuild images on a fixed schedule | Ensures upstream patches actually reach production | Ongoing, low effort |
| Keep default seccomp and AppArmor profiles enabled | Restricts syscalls available to a compromised process | No effort — do not disable |
Store secrets via a secrets manager, never ENV or baked into the image | Prevents credential leakage via image layers or docker history | Half a day |
Beyond the technical controls, container compromises carry compliance weight for Indian organisations. A breach that exposes personal data processed inside a compromised container is a reportable incident under the DPDP Act 2023, and demonstrating reasonable security safeguards — including container hardening — is directly relevant to DPDP compliance obligations, not just an engineering best practice.
Runtime hardening reduces risk, but it does not tell you which containers, images, and hosts are actually exposed right now. A free VAPT scan checks externally reachable services — including misconfigured container endpoints and exposed daemon interfaces — the same way an attacker would, and for regulated workloads a full assessment can be delivered with a CERT-In empanelled partner. Bachao.AI, built by Dhisattva AI Pvt Ltd, a DPIIT Recognised Startup, runs this scan automatically.