Docker

Lesson 06

Non-root users and permissions

Run application processes as a non-root user and make file ownership match the runtime user.

Good Code

Dockerfile
FROM node:22-alpine AS runtime

WORKDIR /app
RUN addgroup -S app && adduser -S app -G app

COPY --chown=app:app package.json package-lock.json ./
RUN npm ci --omit=dev
COPY --chown=app:app server.js ./server.js

USER app
CMD ["node", "server.js"]

Bad Code

Dockerfile
FROM node:22-alpine

WORKDIR /app
COPY . .
RUN npm install

CMD ["node", "server.js"]

Review Notes

What to review

Good Code

The good version creates a dedicated user, assigns ownership during copy, and switches to that user before the process starts.

Bad Code

The bad version runs as the default root user. A compromised process gets more privileges inside the container than it needs.

Takeaways

  • Containers should not need root at runtime unless the application has a specific reason.