After the emersion of the runC container runtime bug it’s finally the time to run processes in Docker containers as non-root user. This article shows you how to achieve that with your Python applications.

Using requirements.txt

If your project uses a plain requirements.txt , you can use the following snippet to run your application as non-root process in the Docker container.


FROM python:3.7.2-alpine

RUN pip install --upgrade pip

RUN adduser -D worker
USER worker
WORKDIR /home/worker

COPY --chown=worker:worker requirements.txt requirements.txt
RUN pip install --user -r requirements.txt

ENV PATH="/home/worker/.local/bin:${PATH}"

COPY --chown=worker:worker . .

LABEL maintainer="Your Name <your-mail@example.com>" \
      version="1.0.0"

CMD ["python"]

pip is upgraded before using a worker user, because it’s installed as root and can’t be accessed by a non-root user. After switching the current user to the worker user every COPY instruction needs the --chown=<user>:<group> flag to signal to change the file or directory owner to the worker user (it’s root by default).

Running pip install with the --user flag installs the dependencies for the current user in the .local/bin directory in the users home directory. Therefore, we need to add this newly created directory to the PATH environment variable.

Using Pipenv

As many projects use Pipenv to handle their dependencies, here’s a way to run your Python applications, which depend on Pipenv, as non-root process in a Docker container.


FROM python:3.7.2-alpine

RUN pip install --upgrade pip

RUN adduser -D worker
USER worker
WORKDIR /home/worker

RUN pip install --user pipenv

ENV PATH="/home/worker/.local/bin:${PATH}"

COPY --chown=worker:worker Pipfile Pipfile
RUN pipenv lock -r > requirements.txt
RUN pip install --user -r requirements.txt

COPY --chown=worker:worker . .

CMD ["python"]

This one is very similar to the previous one. Notice that the .local/bin directory is added to the PATH environment variable right after Pipenv is installed. As Pipenv itself is installed with the --user flag, it’s installed inside the .local/bin directory. To make use of it in line 14, it has to be added to PATH .

Conclusion

I hope this short article helps you running your Python applications safely as non-root user in a Docker container. If there are any questions, feel free to leave a comment or contact me via Twitter. Make sure to share it with your friends if you think it’s a helpful article. Thanks for reading, stay curious and keep coding!