Docker
Container Management
DevOps
Software Development
Container Capabilities

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:

bash
docker run --cap-add NET_ADMIN myimage:latest

but not an equivalent "attach this capability later" command for a live container.

Many people look for something like:

bash
# This is not a supported Docker feature
docker update --cap-add NET_ADMIN mycontainer

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:

bash
docker exec -it mycontainer sh -c 'grep CapEff /proc/1/status'

If the image has capsh, you can get a more readable view:

bash
docker exec -it mycontainer sh -c 'capsh --print'

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.

bash
1docker stop mycontainer
2docker rm mycontainer
3
4docker run -d \
5  --name mycontainer \
6  --cap-add SYS_PTRACE \
7  -p 8080:8080 \
8  myimage:latest

If the workload stores data, use volumes so recreation is routine instead of destructive:

bash
1docker run -d \
2  --name mycontainer \
3  --cap-add NET_ADMIN \
4  -v app-data:/var/lib/app \
5  myimage:latest

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:

yaml
1services:
2  app:
3    image: myimage:latest
4    cap_add:
5      - NET_ADMIN
6      - SYS_PTRACE

In Kubernetes, the equivalent is part of the container securityContext:

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: debug-pod
5spec:
6  containers:
7    - name: app
8      image: alpine:3.20
9      command: ["sh", "-c", "sleep 3600"]
10      securityContext:
11        capabilities:
12          add:
13            - SYS_PTRACE

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:

  1. confirm the exact operation that failed
  2. identify the smallest capability that enables it
  3. recreate the container with that one capability
  4. 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:

  1. observe the permission failure
  2. inspect the current capability set
  3. verify that the missing privilege is truly a capability issue
  4. update the deployment definition
  5. 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 exec to change the container's privileges. It only starts another process inside the existing security profile.
  • Using --privileged when 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.

Course illustration
Course illustration

All Rights Reserved.