In this lesson, you will learn how to configure your Dockerfiles to run applications as a non-privileged user, effectively locking the door against potential intruders.
The Principle of Least Privilege
By default, processes inside a Docker container run as the root user. If an attacker manages to exploit a vulnerability in your application—such as a remote code execution bug—they inherit that root access. Because the container shares the host's kernel, an attacker with root privileges inside the container has a much higher chance of "breaking out" to compromise the host machine itself.
To mitigate this, we enforce the principle of least privilege by creating a specific user and group for our application, ensuring the process has only the permissions it strictly needs to function.
Implementing Non-Root Execution
You should define a user at the end of your Dockerfile. This ensures that while you might need root privileges to install dependencies or copy files during the build process, the final runtime environment is locked down.
Here is how you do it:
# Use a formal base image
FROM node:18-slim
# Create a group and user
RUN groupadd -r myappgroup && useradd -r -g myappgroup myappuser
# Set the working directory and change ownership
WORKDIR /app
COPY . .
RUN chown -R myappuser:myappgroup /app
# Switch to the non-privileged user
USER myappuser
# The application now runs as 'myappuser'
CMD ["node", "app.js"]
Why This Matters
When you set the USER instruction, any subsequent command—including your CMD or ENTRYPOINT—executes under that user identity. If an attacker gains control of your application, they are trapped in the context of myappuser. They won't be able to modify system files, install malicious software, or interact with sensitive host resources that require root permissions.
This is a critical layer of defense-in-depth. Even if your code has a security flaw, non-root execution acts as a final firewall, severely limiting the damage an attacker can inflict on your infrastructure.
Key Takeaway: Always configure your Dockerfiles to switch to a non-privileged user to contain potential breaches and minimize the impact of container escapes.