Back to course

Lesson 24: Non-Root Users and Container Security Best Practices

Docker Zero to Hero: The Complete Containerization Course for Beginners

Lesson 24: Non-Root Users and Container Security Best Practices

Security should be a priority. By default, processes inside a Docker container run as the root user, which is a major security risk.

The Root Problem

If a malicious actor gains control of a container running as root, they might exploit a vulnerability in the Docker daemon or the Linux kernel to gain root access to the host machine.

Solution: The USER Instruction

The USER instruction in a Dockerfile sets the user (by name or UID) that will execute all subsequent commands (RUN, CMD, ENTRYPOINT).

Example: Creating and Using a Dedicated User

  1. Create the user and group: dockerfile FROM alpine:latest

    Create a non-root group and user

    RUN addgroup -S appgroup && adduser -S appuser -G appgroup

    WORKDIR /app

    Ensure the new user owns the application directory

    RUN chown -R appuser:appgroup /app

    Switch to the non-root user

    USER appuser

    The CMD will now run as 'appuser'

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

  2. Using Pre-built Users: Many base images (like Node.js, Python, or Alpine) already provide non-root users you can switch to immediately, like node or python.

    dockerfile FROM node:20-slim

    Switch directly to the user provided by the base image

    USER node

    WORKDIR /home/node/app COPY . .

    CMD ["npm", "start"]

Other Security Tips

  • Use Small Base Images: Use alpine or slim images instead of full OS images (e.g., ubuntu) to minimize attack surface.
  • Use Multi-Stage Builds (Lesson 21): Eliminate unnecessary build tools from the final image.
  • Restrict Capabilities: Use the --cap-drop flag during docker run to remove unnecessary kernel capabilities from the container.