Docker Compose check · critical

pid: host in Docker Compose

pid: host puts the container in the host's process namespace instead of its own. Processes inside can list every process on the machine with its command line, and with enough privileges send signals to them or inspect their memory. The explainer marks it critical. Remove it unless the service is a host-level debugging or monitoring tool you trust.

$ explain docker-compose.yml
! app shares the host PID namespace critical
line 4
fix: see below
$ 

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

Why it matters

A normal container only sees its own processes. With `pid: host` it sees everything on the host, including command lines, which often carry configuration and sometimes secrets passed as arguments.

Root in the container keeps the default capability to send signals, so it can stop host processes. With `SYS_PTRACE` added, it can also attach to them and read their memory.

Combined with other loosened settings, such as privileged mode or `cap_add: [SYS_ADMIN]`, a shared PID namespace makes it straightforward to enter the namespaces of a host process and run commands as that process.

Risky and safer docker-compose.yml

Riskydocker-compose.yml
services:
  app:
    image: example/app:1.4.2
    pid: host
    restart: unless-stopped
    mem_limit: 512m
Saferdocker-compose.yml
services:
  app:
    image: example/app:1.4.2
    # No pid key: the container gets its own process namespace
    restart: unless-stopped
    mem_limit: 512m

How to fix it

  • Remove pid: host.
  • If two services need to see each other's processes, share between them with pid: "service:<name>" instead of the host namespace.
  • Run host-level debugging tools only when needed, with docker run on the host, rather than leaving them in a long-running stack.

When it's acceptable

  • Trusted host monitoring or profiling agents that are designed to observe every process on the machine.
  • A short debugging session on your own machine, removed when you are done.

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 pid (opens in a new tab)

    Shares the host's process namespace, so the container can see every process on the host.

    The container can see and signal every process on the host, and inspect their memory with enough privileges.

    Safer: Remove pid: host so the container gets its own process namespace.

  • 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 pid: host do in docker-compose?

It makes the container use the host's process namespace, so processes inside see all host processes and their command lines instead of only their own.

Can a container with pid: host kill host processes?

Yes, if it runs as root with the default capabilities: it can send signals to any process it can see. With SYS_PTRACE it can also attach to them.

How can two containers share processes without pid: host?

Set pid: "service:other" on one of them. It joins the other container's process namespace and still cannot see the rest of the host.