Running as Non-root
Use the USER instruction so your app runs without root privileges, limiting the damage if the container is compromised.
USER appuserBy default, processes inside a container run as root. If an attacker breaks out of the app, root inside the container is a dangerous starting point. Running as a non-root user is a key hardening step.
The USER instruction
Add a USER instruction in your Dockerfile to switch to an unprivileged user for the rest of the build and at runtime. Many official images already include a suitable user (for example, node).
Creating a user
If no suitable user exists, create one with adduser and make sure it owns the files it needs.
Example
FROM python:3.12-slim
# Create an unprivileged user
RUN useradd --create-home --uid 10001 appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
RUN pip install --no-cache-dir -r requirements.txt
# Drop root before running the app
USER appuser
CMD ["python", "main.py"]When to use it
- A security team requires all containers to run as a non-root user so that a container escape does not immediately grant root on the host.
- A compliance audit flags containers running as UID 0; the team fixes this by adding a USER instruction to every Dockerfile.
- An Nginx container is configured to run as a non-privileged user by switching to a rootless Nginx image on port 8080.
More examples
Create and switch to a non-root user
Uses the pre-created 'node' user that the node:alpine image includes, and chown-copies files so the user can read them.
FROM node:20-alpine
WORKDIR /app
COPY --chown=node:node package*.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
# Switch to the built-in 'node' user
USER node
CMD ["node", "index.js"]Create a dedicated app user
Creates a dedicated non-root user and group, copies files with correct ownership, then switches before CMD.
FROM python:3.12-slim
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
RUN pip install --no-cache-dir -r requirements.txt
USER appuser
CMD ["python", "app.py"]Verify container runs as non-root
Confirms the container process is running as a non-root user by printing the effective user identity.
docker run --rm myapp whoami
# Should print: node (or appuser), not root
# Check numeric UID
docker run --rm myapp id
Discussion