Running linux processes as root is not a good idea. One problem or exploit with the process can give to the attacker a root shell. When we run one docker container, especially if this container is in production it shouldn’t be run as root.
To do that we only need to generate a Dockerfile to properly run our Python/Django application as non-root. That’s my boilerplate:
FROM python:3.8 AS base
ENV APP_HOME=/src
ENV APP_USER=appuser
RUN groupadd -r $APP_USER && \
useradd -r -g $APP_USER -d $APP_HOME -s /sbin/nologin -c "Docker image user" $APP_USER
WORKDIR $APP_HOME
ENV TZ 'Europe/Madrid'
RUN echo $TZ > /etc/timezone && apt-get update && \
apt-get install -y tzdata && \
rm /etc/localtime && \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata && \
apt-get clean
RUN pip install --upgrade pip
FROM base
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt .
RUN pip install -r requirements.txt
ADD src .
RUN chown -R $APP_USER:$APP_USER $APP_HOME
USER $APP_USER
Also, in a Django application, we normally use a nginx as a reverse proxy. Nginx normally runs as root at it launches its process as non-root, but we also can run nginx as non-root.
FROM nginx:1.17.4
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/conf.d
COPY etc/nginx.conf /etc/nginx/nginx.conf
RUN chown -R nginx:nginx /var/cache/nginx && \
chown -R nginx:nginx /var/log/nginx && \
chown -R nginx:nginx /etc/nginx/conf.d && \
chmod -R 766 /var/log/nginx/
RUN touch /var/run/nginx.pid && \
chown -R nginx:nginx /var/run/nginx.pid && \
chown -R nginx:nginx /var/cache/nginx
USER nginx
And that’s all. Source code of a boilerplate application in my github
After changing my Dockerfile to create a user and set its permissions like yours, my Image failed to recognize the Django settings module “myproject.settings”. I still have not found a successful way to avoid this error when running as non-root. I’m struggling to understand how your dockerfile creates an image that successfully runs Django considering it sets the user the same way mine does.
Take care if you are using external volumes in
docker. Maybe you have files owned by root an nonroot at same time. Try to remove all (containers and volumes) and build all again