Introduction
When working with Docker containers, setting up user permissions is crucial for both security and functionality. Running processes as non-root users inside a container helps minimize potential security vulnerabilities. This tutorial explores how to add users and manage permissions within Docker containers effectively.
Understanding Users in Docker Containers
Docker containers operate under the root user by default when built using base images like Ubuntu or Alpine Linux. However, for enhanced security, it’s recommended to create non-root users who will run specific processes inside these containers. This approach limits what a potential attacker can do if they compromise your application running within the container.
Creating Users in Dockerfiles
To add users in a Dockerfile, you typically use commands such as useradd
, adduser
, or their equivalents from BusyBox on Alpine Linux images. Here’s how to accomplish this:
Using useradd
useradd
is preferred over its interactive counterpart adduser
because it allows non-interactive additions of users with various options.
Example:
FROM ubuntu:14.04
# Add a user without requiring input for password or personal information
RUN useradd -ms /bin/bash uwsgi && \
useradd -ms /bin/bash celery
USER uwsgi
WORKDIR /home/uwsgi
Explanation:
-m
: Creates the home directory for the new user.-s /bin/bash
: Sets/bin/bash
as the default shell.
Using adduser
with Non-Interactive Flags
On distributions like Ubuntu, you can use adduser
non-interactively by passing specific flags:
FROM ubuntu:14.04
# Add users without interactive prompts
RUN adduser --disabled-password --gecos '' uwsgi && \
adduser --disabled-password --gecos '' celery
USER uwsgi
WORKDIR /home/uwsgi
Explanation:
--disabled-password
: Avoids setting a password, which is useful in automated builds.--gecos ''
: Skips the additional user information prompts.
BusyBox on Alpine Linux
For Alpine-based containers, you use BusyBox’s version of adduser
:
FROM alpine:latest
# Add users without interactive prompts
RUN adduser -D -g '' uwsgi && \
adduser -D -g '' celery
USER uwsgi
WORKDIR /home/uwsgi
Explanation:
-D
: Disables the creation of a password for the user.-g ''
: Skips entering group information.
Assigning Permissions and Group Management
Once users are created, you may want to assign them specific permissions or place them in groups:
# Create a group and add both users to it
RUN groupadd workers && \
usermod -aG workers uwsgi && \
usermod -aG workers celery
# Set directory ownership for the worker group
RUN chown -R :workers /app
Explanation:
groupadd
: Creates a new user group.usermod -aG
: Adds users to supplementary groups without removing them from existing ones.
Security Best Practices
-
Run as Non-root User: Always specify a non-root user for running your applications within the container using the
USER
directive in your Dockerfile. -
Minimal Permissions: Assign only the necessary permissions and group memberships required by the application processes.
-
Avoid Hardcoding Sensitive Information: For sensitive operations, such as setting passwords, consider externalizing these configurations or securely handling them through environment variables.
Conclusion
Creating non-root users and managing user permissions within Docker containers is an essential part of securing containerized applications. By following the best practices outlined in this tutorial, you can significantly reduce security risks associated with running processes as the root user inside containers. Always aim to follow open-source examples or established patterns for guidance on effective permission management.