How do you run a container as a non-root user using the Dockerfile USER instruction?
Create an unprivileged user with RUN, then switch with USER before CMD. All later instructions and the running process then use that user, which limits the damage if the app is compromised.
Explain it simply
By default a container process runs as root inside the container. Giving root to a web app is like giving the peon the master key to the whole college.
USER appuser switches the identity for every following instruction and for the main process. First you must create that user, since base images rarely have one: on Debian-based images use useradd, on Alpine use adduser -D. Many official images ship a ready user, such as node in node images. Remember file ownership: use COPY --chown=appuser:appuser so the app can read or write its own files, and avoid ports below 1024, which non-root users cannot bind in many setups.
If an attacker escapes the app, they land as an ordinary user, not as root.
Example
FROM node:20-alpine
WORKDIR /app
COPY --chown=node:node . .
RUN npm ci --omit=dev
USER node
CMD ["node", "server.js"]What to say in the interview
"I create or reuse an unprivileged user, set file ownership with COPY --chown, and add USER before CMD so the process does not run as root. This limits the impact of a compromise."
Common mistakes
- Adding USER before the RUN steps that need root to install packages.
- Forgetting --chown, so the app cannot write to its folder.