# Problem:FROMnode:20CMD["node","server.js"]# Runs as root by default
Example
# Fix:FROMnode:20-alpine
WORKDIR/app
COPY--chown=node:node..RUNnpm ci --omit=dev
USERnodeCMD["node","server.js"]
Note Most base images default to root. This means if an attacker exploits your application, they have root inside the container - and potentially on the host via privilege escalation. Always add a USER instruction before CMD.
# NEVER do this:ENV DATABASE_URL=postgres://user:pass@host/db
COPY.env/app/.env
Example
# Bad - secret is in the image layer history:ENV API_KEY=sk-abc123...# Fix - pass secrets at runtime:docker run -e API_KEY=sk-abc123 myapp:1.0docker run --env-file.env myapp:1.0# For build-time secrets (e.g., private npm token):docker build --secret id=npmrc,src=.npmrc.# In Dockerfile:RUN--mount=type=secret,id=npmrc,target=/root/.npmrcnpm ci
Note ENV values and COPYed files are permanently visible via docker history and docker inspect. Even if you delete them in a later layer, they exist in the previous layer. Use --secret mounts for build-time secrets and runtime env vars or secret managers for runtime secrets.
Frequently asked questions
How does Docker handle security mistake?
Docker covers this with 2 copy-ready snippets on this page. The "Running Containers as Root" snippet in Docker uses `# Problem:`.
Which command does the Docker example use?
The "Running Containers as Root" snippet uses `# Problem:`, from the Common Mistakes section of the Docker cheat sheet.
What other Docker snippets are shown for "security mistake"?
Besides "Running Containers as Root", this page also shows "Baking Secrets into Images".
Is there anything to watch out for?
Yes. For "Running Containers as Root": Most base images default to root. This means if an attacker exploits your application, they have root inside the container - and potentially on the host via privilege escalation. Always add a USER instruction before CMD.