DEV Community

Sreekanth Kuruba
Sreekanth Kuruba

Posted on

Docker Security Internals: How Safe Are Your Containers Really?

post 6:

You run containers every day.

But have you ever asked yourself this uncomfortable question:

If one container gets compromised… can it break out and take down the entire host?

Most people assume containers are “secure by default.”

They’re not.

They’re isolated by default — and isolation is not the same as security.

This post explains how Docker security actually works under the hood, what the real risks are, and how to harden your containers properly.


1. The Foundation: Linux Kernel Features

Docker doesn’t invent its own security model.

It relies heavily on existing Linux kernel features:

  • Namespaces → Isolation of processes, network, filesystem, and more
  • cgroups → Resource limits for CPU, memory, and I/O
  • Capabilities → Fine-grained control over root privileges
  • seccomp → Filtering of potentially dangerous system calls
  • AppArmor / SELinux → Mandatory Access Control

Understanding these layers is the key to understanding container security.


2. Namespaces – Isolation, Not Security

Namespaces give each container its own private view of the system.

For example:

  • PID namespace → Container processes are isolated from host processes
  • Network namespace → Container gets its own network stack
  • Mount namespace → Container gets its own filesystem view
  • User namespace → Container users can be mapped to unprivileged users on the host

This isolation is powerful — but it isn't perfect.

All containers still share the same Linux kernel.

That means a serious kernel vulnerability could potentially affect the host and other containers.

Namespaces provide isolation, not complete security.


3. cgroups – Preventing Resource Exhaustion

Namespaces control what a container can see.

cgroups control how much of the host's resources it can consume.

Without resource limits, a single container could potentially:

  • Consume excessive CPU
  • Exhaust available memory
  • Generate excessive disk I/O

For example:

docker run --memory=512m --cpus=1.0 nginx
Enter fullscreen mode Exit fullscreen mode

Here:

  • --memory=512m limits memory usage
  • --cpus=1.0 limits CPU usage

This helps prevent one container from consuming an unreasonable amount of the host's resources.


4. The Root Problem – Still Real

By default, many containers run as root (UID 0) inside the container.

However, Docker starts containers with a reduced set of Linux capabilities, limiting what that root process can do.

This significantly reduces the attack surface.

But container root is still something to take seriously.

If an application is compromised and has excessive privileges, combined with a kernel or runtime vulnerability, an attacker could potentially attempt a container escape.

A good practice is to run applications as a non-root user whenever possible.

For example, in a Dockerfile:

FROM nginx:alpine

USER 1000
Enter fullscreen mode Exit fullscreen mode

Also avoid using:

--privileged
Enter fullscreen mode Exit fullscreen mode

unless there is a specific, well-understood requirement.

The --privileged option grants a container significantly more access to the host and disables or weakens several isolation protections.


5. seccomp – Blocking Dangerous System Calls

seccomp (Secure Computing Mode) is another important Docker security layer.

Applications interact with the Linux kernel through system calls.

A compromised application could potentially try to use unusual or dangerous system calls to interact with the kernel.

Docker provides a default seccomp profile that blocks many system calls that containers typically don't need.

You can also apply a custom, stricter profile:

docker run \
  --security-opt seccomp=/path/to/custom-profile.json \
  nginx
Enter fullscreen mode Exit fullscreen mode

This can further reduce the container's attack surface.

The key idea is simple:

If an application doesn't need a system call, don't give it access to that system call.


6. Rootless Docker – Reducing Host-Level Risk

Traditional Docker deployments commonly use a Docker daemon that requires root privileges.

This creates an important security consideration because access to the Docker daemon can provide powerful control over containers and, depending on configuration, the host.

Rootless Docker allows the Docker daemon and containers to operate without requiring root privileges.

Container root can be mapped to an unprivileged user on the host.

This reduces the potential impact of certain container or daemon compromises.

Rootless Docker is particularly useful in environments where reducing host-level privileges is important, although it can have some feature and compatibility limitations.


7. Practical Docker Hardening Checklist

Here are some practical steps you can apply:

  • Run containers as a non-root user whenever possible
  • Use official and regularly updated base images
  • Enable Rootless Docker when it fits your environment
  • Use --read-only for the container filesystem when the application allows it
  • Set resource limits such as --memory and --cpus
  • Keep Docker's default seccomp profile unless you have a reason to change it
  • Use AppArmor or SELinux where appropriate
  • Scan images regularly with tools such as Trivy or Docker Scout
  • Avoid --privileged unless there is a specific requirement
  • Keep Docker Engine and container images updated

Security is not achieved by using just one of these controls.

It comes from multiple layers working together.


Summary

Docker security is not magic.

It is a combination of multiple Linux and Docker security mechanisms:

  • Namespaces → Process and resource isolation
  • cgroups → Resource control
  • Capabilities → Privilege reduction
  • seccomp → System call filtering
  • AppArmor / SELinux → Mandatory Access Control
  • Rootless Docker → Reduced host-level privileges

Default Docker settings provide a useful level of isolation, but production environments often require deliberate security hardening.

The important thing to remember is:

Containers are isolated, but isolation alone does not make them secure.

Understanding what happens underneath Docker helps you move from:

“It works.”

to

“It works — and it’s properly secured.”


Next Topic

Docker Compose Internals – How It Orchestrates Multi-Container Applications

Top comments (0)