How can we add capabilities to a running docker container?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Linux capabilities give a process narrow slices of privilege such as NET_ADMIN or SYS_PTRACE without granting full unrestricted root access. Docker uses those capabilities as part of the container security profile. The key limitation is that Docker assigns capabilities when the container is created, so you cannot cleanly add new ones to a container that is already running.
Why Capabilities Are Set at Container Start
When Docker starts a container, it creates the namespaces, cgroups, seccomp profile, capability set, and device access rules that define that container's runtime boundary. Those settings are not meant to drift later. That design keeps the runtime simpler and makes container security reproducible.
In practice, that means Docker supports commands like this at startup:
but not an equivalent "attach this capability later" command for a live container.
Many people look for something like:
That command does not exist because capability changes are creation-time settings.
Inspect the Current Capability Set
Before recreating a container, confirm what it already has. A quick check from inside the container is:
If the image has capsh, you can get a more readable view:
This is useful when the actual problem is not a missing capability at all. Sometimes the failure is caused by seccomp, a missing device mount, or ordinary file permissions.
The Supported Fix: Recreate the Container
If you truly need a new capability, the correct workflow is to stop and recreate the container with the required --cap-add flag.
If the workload stores data, use volumes so recreation is routine instead of destructive:
This is one of the core Docker operating assumptions: containers are replaceable, so important mutable state should live outside the writable container layer.
Use Declarative Definitions for Repeatability
If you are using Compose, put the capability in the service definition so every restart uses the same security profile:
In Kubernetes, the equivalent is part of the container securityContext:
The same rule applies there as well: the pod must be recreated for the change to take effect.
Avoid --privileged Unless You Mean It
When one missing capability causes trouble, teams often jump to --privileged. That usually works, but it removes far more isolation than necessary.
A better escalation order is:
- confirm the exact operation that failed
- identify the smallest capability that enables it
- recreate the container with that one capability
- keep the rest of the security profile unchanged
For example, if a debugger needs tracing, SYS_PTRACE is a much tighter fix than full privileged mode.
Common Operational Pattern
In real environments, the clean workflow looks like this:
- observe the permission failure
- inspect the current capability set
- verify that the missing privilege is truly a capability issue
- update the deployment definition
- recreate or roll out a replacement container
That gives you an auditable change and prevents the same issue from returning on the next restart.
Common Pitfalls
- Expecting
docker execto change the container's privileges. It only starts another process inside the existing security profile. - Using
--privilegedwhen one narrow capability would be enough. - Recreating a stateful container without externalizing data first.
- Updating a live container manually but forgetting to update Compose or Kubernetes configuration.
- Misdiagnosing a seccomp or device-access failure as a capability problem.
Summary
- Docker capabilities are assigned when the container starts.
- You cannot add a new capability to a container that is already running.
- The supported fix is to recreate the container with
--cap-add. - Prefer the smallest required capability over full privileged mode.
- Keep the change in Compose or Kubernetes manifests so it survives future restarts.

