Docker Compose check · critical

privileged: true in Docker Compose

privileged: true runs the container with every Linux capability, access to all host devices and the default seccomp and AppArmor profiles turned off. A compromise of the app inside is then close to a compromise of the host, so the explainer marks it critical.

$ explain docker-compose.yml
! app runs privileged critical
line 4
fix: see below
$ 

What the free Docker Compose explainer reports on the risky example below.

Why it matters

Docker's isolation is a stack of separate controls: a reduced capability set, a seccomp filter, an AppArmor or SELinux profile and a device allow-list. Privileged mode switches all of them off at once.

With it, a process in the container can load kernel modules, mount the host's disks and reach /dev directly. Those are the usual first steps of a container escape, and none of them needs a kernel bug.

It is often added to get one thing working (a USB device, a FUSE mount, Docker-in-Docker) and then never removed, so the service keeps far more power than it uses.

Risky and safer docker-compose.yml

Riskydocker-compose.yml
services:
  app:
    image: example/app:1.4.2
    privileged: true
    restart: unless-stopped
    mem_limit: 512m
Saferdocker-compose.yml
services:
  app:
    image: example/app:1.4.2
    # Only what the service needs, instead of privileged: true
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    restart: unless-stopped
    mem_limit: 512m

How to fix it

  • Remove privileged: true.
  • Start the service and note what fails. Grant just that: one capability with cap_add, one device with devices, or a specific mount.
  • Avoid cap_add: [ALL] and SYS_ADMIN, which the explainer also flags: they are nearly as broad as privileged mode.
  • For Docker-in-Docker, prefer a rootless builder (BuildKit rootless, Kaniko) over a privileged daemon.

When it's acceptable

  • A throwaway local container for hardware or kernel experiments that never runs untrusted input.
  • Tools that genuinely manage the host (some monitoring or storage agents) and are trusted to that level. Even then, check whether their documentation lists a narrower set of capabilities.

Check your own docker-compose.yml

The risky example is loaded below. Paste your own file to check it for this and every other Docker Compose rule. It runs in your browser; nothing is uploaded.

docker-compose.yml

Parsed in your browser. Nothing is uploaded.

Explanation

1 service0 networks0 volumes1 critical

Top level

appexample/app:1.4.2

  • Docs for image (opens in a new tab)

    Runs the image example/app:1.4.2.

  • Docs for privileged (opens in a new tab)

    Gives the container full access to the host: all capabilities and access to host devices. Use only when you really need it.

    A privileged container has nearly full access to the host, so a compromise of the app is a compromise of the machine.

    Safer: Remove privileged: true and add only the specific capabilities or devices the service needs.

  • Docs for restart (opens in a new tab)

    Restarts if it stops or after a daemon restart (unless-stopped), but stays down if you stopped it manually.

  • Docs for mem_limit (opens in a new tab)

    Limits memory to 512m. The container is killed if it exceeds this.

Questions

What does privileged: true do in docker-compose?

It gives the container all Linux capabilities, access to every host device, and turns off the default seccomp and AppArmor profiles. The container keeps its own filesystem and process view, but most of the barriers between it and the host are gone.

Is privileged: true the same as running as root?

No, it is broader. Root inside a normal container is still limited by dropped capabilities and seccomp. Root inside a privileged container has those limits removed, which is why privileged mode is treated as close to root on the host.

What should I use instead of privileged mode?

Grant only what the service needs: a single capability with cap_add, a single device with devices, or a specific bind mount. Most services that ask for privileged mode need one of these.