Dockerfile check · medium

sudo installed or used in a Dockerfile

Build steps already run as root until a USER line changes that, so sudo is unnecessary during the build. Installing it and granting the runtime user sudo rights gives that non-root user a way back to root at run time, which undoes the protection USER was meant to provide. Do root steps before USER and give the app user ownership of only what it needs.

$ explain Dockerfile
! RUN installs or uses sudo medium
line 2
fix: see below
$ 

What the free Dockerfile explainer reports on the risky example below.

Why it matters

A passwordless sudo rule for the app user means anyone who compromises the app can become root inside the container with one command.

sudo is unpredictable in containers: it expects a TTY and specific environment handling. Docker's best-practice guidance is to avoid it and use a tool such as gosu if an entrypoint really must drop privileges.

The explainer flags any RUN that mentions sudo as a command, whether it installs the package or calls it.

Risky and safer Dockerfile

RiskyDockerfile
FROM debian:12-slim
RUN apt-get update \
 && apt-get install -y --no-install-recommends sudo ca-certificates \
 && rm -rf /var/lib/apt/lists/* \
 && useradd -u 10001 -m app \
 && echo "app ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/app
COPY app /usr/local/bin/app
USER 10001
HEALTHCHECK CMD ["/usr/local/bin/app", "health"]
CMD ["/usr/local/bin/app"]
SaferDockerfile
FROM debian:12-slim
RUN apt-get update \
 && apt-get install -y --no-install-recommends ca-certificates \
 && rm -rf /var/lib/apt/lists/* \
 && useradd -u 10001 -m app
COPY app /usr/local/bin/app
USER 10001
HEALTHCHECK CMD ["/usr/local/bin/app", "health"]
CMD ["/usr/local/bin/app"]

How to fix it

  • Remove sudo and any sudoers entries from the image.
  • Run every step that needs root before the USER line; RUN already runs as root there, so prefixing commands with sudo does nothing useful.
  • Give the runtime user ownership of the specific directories it writes to (chown), and nothing else.
  • If the entrypoint must start as root and then drop privileges, use a small tool such as gosu rather than sudo.

When it's acceptable

  • Development or devcontainer images where a person works interactively inside the container and needs to install tools. Don't ship those images to production.

Check your own Dockerfile

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

Dockerfile

Parsed in your browser. Nothing is uploaded.

Explanation

1 stage6 instructions1 medium1 low

Stage 0debian:12-slim

  • Docs for FROM (opens in a new tab)

    Starts from the base image debian, tag 12-slim.

    A version tag can be re-pushed to different content; only a digest is immutable. This applies to every tagged FROM in the file.

    Safer: Pin the digest as well (image:tag@sha256:<digest>) and let a bot open pull requests when it changes.

  • Docs for RUN (opens in a new tab)

    Runs apt-get update && apt-get install -y --no-install-recommends sudo ca-certificates && rm -rf /var/lib/apt/lists/* && user… while building the image and saves the result as a new layer.

    sudo gives a non-root user a way back to root, which undoes the point of a USER instruction.

    Safer: Drop sudo. Do the steps that need root before the USER line, and give the runtime user ownership of only what it needs.

  • Docs for COPY (opens in a new tab)

    Copies app from your build context to /usr/local/bin/app in the image.

  • Docs for USER (opens in a new tab)

    Runs later instructions and the container's process as user 10001.

  • Docs for HEALTHCHECK (opens in a new tab)

    Runs /usr/local/bin/app health to check the container is healthy.

  • Docs for CMD (opens in a new tab)

    Sets the default command to /usr/local/bin/app. It runs when the container starts, and anything passed to docker run replaces it.

Questions

Do I need sudo in a Dockerfile?

No. RUN steps run as root unless an earlier USER changes that, so put root steps before USER instead of using sudo.

Why is sudo not found in my Docker build?

Most base images don't include it, because build steps already run as root. Remove the sudo prefix and place the step before your USER line.

What should I use instead of sudo in a Docker entrypoint?

If a script must do something as root and then run the app as another user, Docker's guidance suggests gosu. Better still, avoid needing root at run time at all.