Bird
Raised Fist0
Dockerdevops~5 mins

Running containers as non-root in Docker - Commands & Configuration

Choose your learning style10 modes available
Introduction
Running containers as non-root means the software inside the container does not run with administrator rights. This improves security by limiting what the container can do if it is compromised.
When you want to reduce the risk of a container escaping and affecting the host system.
When running applications that do not need full administrator access inside the container.
When following security best practices for production environments.
When deploying containers in shared environments where multiple users run containers.
When compliance rules require least privilege access for running software.
Config File - Dockerfile
Dockerfile
FROM nginx:1.23.3-alpine

# Create a user and group with a specific ID
RUN addgroup -S appgroup && adduser -S -G appgroup appuser

# Change ownership of the nginx html directory
RUN chown -R appuser:appgroup /usr/share/nginx/html

# Switch to the non-root user
USER appuser

CMD ["nginx", "-g", "daemon off;"]

This Dockerfile starts from the official nginx image.

It creates a new user and group named appuser and appgroup without root privileges.

It changes ownership of the web content directory to this user so nginx can serve files.

Finally, it switches the container to run as appuser instead of root.

Commands
Builds the Docker image named nginx-nonroot using the Dockerfile in the current directory. This image runs nginx as a non-root user.
Terminal
docker build -t nginx-nonroot .
Expected OutputExpected
Sending build context to Docker daemon 2.56kB Step 1/7 : FROM nginx:1.23.3-alpine ---> 3f8a4339aadd Step 2/7 : RUN addgroup -S appgroup && adduser -S -G appgroup appuser ---> Running in 1a2b3c4d5e6f Removing intermediate container 1a2b3c4d5e6f ---> 7f8e9d0c1b2a Step 3/7 : RUN chown -R appuser:appgroup /usr/share/nginx/html ---> Running in 2b3c4d5e6f7g Removing intermediate container 2b3c4d5e6f7g ---> 8a9b0c1d2e3f Step 4/7 : USER appuser ---> Running in 3c4d5e6f7g8h Removing intermediate container 3c4d5e6f7g8h ---> 9b0c1d2e3f4g Step 5/7 : CMD ["nginx", "-g", "daemon off;"] ---> Running in 4d5e6f7g8h9i Removing intermediate container 4d5e6f7g8h9i ---> a0b1c2d3e4f5 Successfully built a0b1c2d3e4f5 Successfully tagged nginx-nonroot:latest
Runs the nginx-nonroot container in detached mode, mapping port 8080 on the host to port 80 in the container. This starts the nginx server as the non-root user.
Terminal
docker run -d -p 8080:80 --name my-nginx-nonroot nginx-nonroot
Expected OutputExpected
b1c2d3e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2
→
-d - Run container in background (detached mode)
→
-p 8080:80 - Map host port 8080 to container port 80
→
--name - Assign a name to the running container
Checks the user ID and group ID inside the running container to confirm it is running as the non-root user.
Terminal
docker exec my-nginx-nonroot id
Expected OutputExpected
uid=1000(appuser) gid=1000(appgroup) groups=1000(appgroup)
Fetches the default nginx welcome page from the container through the mapped port to verify the server is running correctly.
Terminal
curl http://localhost:8080
Expected OutputExpected
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working.</p> </body> </html>
Key Concept

If you remember nothing else from this pattern, remember: running containers as non-root improves security by limiting container permissions.

Common Mistakes
Not changing file ownership to the non-root user inside the container.
The application may fail to start or access files because the non-root user lacks permissions.
Use chown or similar commands in the Dockerfile to give the non-root user ownership of necessary files.
Forgetting to switch the user with the USER instruction in the Dockerfile.
The container will run as root by default, negating the security benefit.
Add USER appuser (or your chosen user) in the Dockerfile before the CMD or ENTRYPOINT.
Running commands that require root privileges after switching to the non-root user.
These commands will fail because the non-root user lacks permissions.
Run all root-required commands before switching users in the Dockerfile.
Summary
Create a non-root user and group inside the Dockerfile.
Change ownership of files the app needs to access to the non-root user.
Switch to the non-root user with the USER instruction before running the app.
Build and run the container, then verify it runs as the non-root user.

Practice

(1/5)
1. Why is it recommended to run Docker containers as a non-root user?
easy
A. To enable root access inside the container
B. To make containers run faster
C. To improve security by limiting container permissions
D. To allow containers to access all host files

Solution

  1. Step 1: Understand container user privileges

    Running containers as root gives full permissions inside the container, which can be risky if the container is compromised.
  2. Step 2: Recognize security benefits of non-root users

    Using a non-root user limits what the container can do, reducing potential damage from attacks.
  3. Final Answer:

    To improve security by limiting container permissions -> Option C
  4. Quick Check:

    Security = D [OK]
Hint: Non-root users limit permissions, improving security [OK]
Common Mistakes:
  • Thinking non-root users make containers faster
  • Believing root is needed for all container tasks
  • Confusing root access with better security
2. Which Dockerfile instruction sets the user to run the container as non-root?
easy
A. RUN
B. CMD
C. ENTRYPOINT
D. USER

Solution

  1. Step 1: Identify Dockerfile instructions for user control

    The USER instruction sets the user and group for running commands inside the container.
  2. Step 2: Differentiate from other instructions

    RUN executes commands during build, CMD and ENTRYPOINT define container start commands but do not set user.
  3. Final Answer:

    USER -> Option D
  4. Quick Check:

    Set user = USER [OK]
Hint: USER sets container run user in Dockerfile [OK]
Common Mistakes:
  • Using RUN to set user (it runs commands)
  • Confusing CMD or ENTRYPOINT with user setting
  • Omitting USER instruction for non-root
3. What is the effect of running this command?
docker run --user 1001 alpine id
medium
A. Shows the user ID 1001 inside the container
B. Runs the container as root user
C. Fails because user 1001 does not exist
D. Shows the container's hostname

Solution

  1. Step 1: Understand the --user flag

    The --user 1001 option runs the container process as user ID 1001 instead of root.
  2. Step 2: Analyze the command output

    The id command inside the container prints the current user info, so it will show UID=1001.
  3. Final Answer:

    Shows the user ID 1001 inside the container -> Option A
  4. Quick Check:

    --user 1001 + id = UID 1001 [OK]
Hint: --user sets UID; id shows current user info [OK]
Common Mistakes:
  • Assuming container runs as root despite --user
  • Thinking id shows hostname
  • Believing command fails if user not in /etc/passwd
4. You wrote this Dockerfile snippet:
FROM alpine
USER appuser
CMD ["sh"]

But when running the container, you get a permission denied error. What is the likely cause?
medium
A. The CMD syntax is incorrect
B. The user 'appuser' does not exist in the image
C. The base image alpine does not support USER
D. The container needs root to run sh

Solution

  1. Step 1: Check if user exists in image

    The USER appuser requires that 'appuser' is created in the image, otherwise permission errors occur.
  2. Step 2: Verify other options

    CMD syntax is correct, alpine supports USER, and sh can run as non-root if permissions allow.
  3. Final Answer:

    The user 'appuser' does not exist in the image -> Option B
  4. Quick Check:

    User must exist = B [OK]
Hint: Create user before USER instruction to avoid permission errors [OK]
Common Mistakes:
  • Assuming USER works without creating user
  • Blaming CMD syntax for permission issues
  • Thinking alpine disallows USER instruction
5. You want to run a container as a non-root user with UID 2000 and GID 3000, but the image has no such user. Which is the best way to do this securely?
hard
A. Add a user with UID 2000 and GID 3000 in the Dockerfile, then use USER
B. Run the container as root and change permissions inside
C. Use --user 2000:3000 without creating the user in the image
D. Modify the host system to add user 2000

Solution

  1. Step 1: Understand user creation in Dockerfile

    To run as a specific non-root user, create that user and group inside the image with matching UID and GID.
  2. Step 2: Use USER instruction to switch user

    After creating the user, use the USER instruction to run container processes as that user securely.
  3. Step 3: Evaluate other options

    Running as root is insecure, using --user without user in image may cause permission issues, and modifying host users is unrelated.
  4. Final Answer:

    Add a user with UID 2000 and GID 3000 in the Dockerfile, then use USER -> Option A
  5. Quick Check:

    Create user + USER = secure non-root run [OK]
Hint: Create user in Dockerfile before USER for secure non-root run [OK]
Common Mistakes:
  • Running as root to avoid user setup
  • Using --user without user in image causing errors
  • Changing host users instead of container users
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard