5.5. Run as a Non-root User#
When we tried to build and run the container last time we got permission errors.
That’s because the container user is root. This is generally a bad idea.
Remember, that the container looks like a complete Linux system with its own
users, that are separate from the system users outside of the container. That
means we need to add users we want to exist in the Dockerfile instructions.
We’ll do that in this lab.
Adding a Unix User#
The useradd command on Linux does exactly what you think it does. Let’s look
at the options:
$ useradd -h
Update the build instructions in your Dockerfile to run the useradd command,
and change to the new user:
# Install packages that are required.
RUN pip install Django==6.0.1 psutil
# Create a user
RUN useradd -d /app -M django
# Switch to the new user
USER django
# Copy the Python code into the container (as the new user)
COPY --chown=django:django djangotutorial /app
# Set environment variables
ENV PORT=8080
With all of the changes to your Dockerfile you now have a complete workable
application.
Try a Build and Run#
This should work now!
$ mkdir ~/data
$ docker build -t myapp .
$ docker run -it --rm \
-u $(id -u):$(id -g) \
-p 8080:8080 \
-v $HOME/data:/data \
myapp
The Complete Dockerfile#
If you got lost and have a broken Dockerfile here’s a complete one:
# Start with the base Python container
# FIXME: Update the version
FROM docker.io/python:3.12.3
# Install packages that are required.
RUN pip install Django==6.0.1 psutil==7.2.2
# Create a user
RUN useradd -d /app -M django
# Copy the Python code into the container
COPY --chown=django:django djangotutorial /app
# Set environment variables
ENV STUDENT_NAME="No Name"
ENV SITE_NAME="www.cis-92.com"
ENV SECRET_KEY="fixme-12345"
ENV DEBUG=1
ENV DATA_DIR="/data"
ENV PORT=8080
ENV DJANGO_SUPERUSER_NAME="test"
ENV DJANGO_SUPERUSER_EMAIL="test@test.test"
ENV DJANGO_SUPERUSER_PASSWORD="test"
# Create the data directory
RUN mkdir $DATA_DIR && chown django:django $DATA_DIR
# Switch to the new user
USER django
# Set the working directory
WORKDIR /app
# Default command to execute in the container
CMD ["/bin/sh", "-c", "./start.sh"]