Docker Command Explainer

Understand a command somebody handed you before you run it. Four things in particular give a container effective control of the host, and none of them looks alarming.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Explain. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A monitoring agent

The socket mount and --privileged together are root on the host with extra steps

docker run -d --name agent -v /var/run/docker.sock:/var/run/docker.sock --privileged myagent:1

Host networking

-p stops doing anything, and loopback-only services become reachable

docker run -d --network host --name proxy nginx

An ordinary command

Every flag explained, and nothing that hands over the host

docker run -d --name web -p 8080:80 -v /srv:/data nginx:alpine

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Mounting the Docker socket read-only and calling it safe

    It is a socket, not a file. Read-only does not stop a write, and a write is an API call that can start a privileged container.

    Instead:Use a socket proxy that allows only the specific API calls needed.

  2. Using --privileged to fix a permissions error

    It grants every capability and disables the security profiles, when the problem is usually one capability or one device.

    Instead:Find the specific need with --cap-add or --device, and start from --cap-drop=ALL.

  3. Putting a docker flag after the image name

    Everything after the image is passed to the container's process, so the flag never reaches Docker and appears to be ignored.

    Instead:Put every docker flag before the image name.

Some flags are equivalent to root on the host

--privileged, --pid=host, --network host and a mount of the Docker socket all remove the boundary the container was supposed to provide.

Mounting the Docker socket is the quietest one

Anything that can talk to it can start a container with --privileged and the host's filesystem mounted, so the isolation is decorative. Adding :ro changes nothing, because the API is a socket rather than a file and read-only does not stop a write to it.

--privileged is every capability at once

Plus device access and no seccomp or AppArmor profile. A process inside can load kernel modules and mount the host filesystem. It is almost always a blunt fix for one missing capability, and finding out which is worth an afternoon.

--pid=host exposes other processes' environments

The container sees and can signal every process on the machine, and can read their /proc entries, which include environment variables and therefore other services' credentials.

--network host removes network isolation

-p stops doing anything, every port the process opens is open on the host, and it can reach services bound to 127.0.0.1 that were meant to be local only.

SYS_ADMIN is close to privileged on its own

It permits mount, and mount permits reaching the host filesystem. NET_ADMIN and SYS_PTRACE are also far broader than their names suggest. Dropping everything with --cap-drop=ALL and adding back what is needed is the shape to aim for.

Everything after the image is arguments to the container

Not to Docker. A flag placed after the image name is passed straight through to the process, which is the commonest reason a flag appears to be ignored.

More docker tools

Docker Container Image Reference Parser Is that a registry or a Docker Hub user? Dockerfile Linter What this image will do to you later docker run to Kubernetes YAML And the flags that have no equivalent Docker Compose to Kubernetes And why depends_on has no equivalent Docker Logging Driver Generator json-file never rotates Dockerfile Non-Root USER Generator Numeric, or Kubernetes rejects it Docker OCI Image Labels Generator One of them actually does something Docker Hub Pull Rate Limit Calculator Counted per IP, not per person Docker Registry Storage Calculator Deleting a tag frees nothing Docker Build Context Analyzer All of it uploads before anything runs Docker Compose to docker run Converter Names stop resolving Docker Compose Version Migrator version: is obsolete now Docker Compose Network and Port Viewer Everything reaches everything Docker BuildKit Cache Mount Generator apt deletes the cache you just mounted Docker BuildKit Secret Mount Generator ARG is in docker history forever Docker .dockerignore Pattern Tester *.log does not match logs/app.log Docker Image Manifest Viewer unknown/unknown is not broken Docker Image Config Viewer Anyone who can pull can read your Env Docker Registry Token Decoder Check the scope before the credentials Docker HEALTHCHECK Generator Docker does nothing when it fails Docker Network Subnet Calculator 31 networks, then it stops Docker History Analyzer The rm did not save anything Docker Run to Compose Converter Some flags have no equivalent Docker CMD and ENTRYPOINT Tester Why docker stop takes ten seconds Docker Port Mapping Tester -p reaches past your firewall Docker -v to --mount Converter -v invents missing directories Docker Restart Policy Simulator The backoff resets after ten seconds Docker Exit Code Explainer 137 is two different problems Docker CPU Limit Converter --cpu-shares limits nothing Docker Memory Limit Calculator -m 512m allows a gigabyte Docker Compose Interpolation Tester An unset variable is an empty string Docker Environment Variable Precedence Tester Your shell does not reach the container Docker Compose Override Merge Previewer An override can add a port, never remove one Dockerfile Multi-Stage Build Analyzer Which stages reach the image Dockerignore Validator It is not .gitignore

Elsewhere on the site