Hello, I’m learning programming and I’m writing first Python application that does something useful, and practical. What is the recommended way to install pip packages when building Docker images? I’m asking because pip install complains about running itself as root. Do you recommend to create venv in Dockerfile? Thank you.
running pip install as root is not recommended in general as far as I know, because it changes system python packages and pip usually recommends using the OS package manager like apt to install python3-PKGNAME if available when the package needed system-wide. I’m not sure how that is better, I just saw that recommendation. I think it is because some packages are already installed through the OS package manager and in that case installing the rest that way is preferred instead of having another collection system-wide python packages.
You can also use virtual environment regardless of Docker.
You can use venv, virtualenv or I often hear about “uv”
While pip is doing a good job of warning you about what not to do on a shared operating system, it doesn’t really apply to Docker container. The Docker container is your virtual environment. It serves one purpose and that is to prepare that environment for your application, and your application only. So breaking system packages for some other application that will never be installed is a non-issue.
I like @rimelek‘s suggestion of using uv. That’s a great tool. I’d like to offer another solution that supports installing Python packages in the container’s system space without complaining. That is Pipenv. You can manage your virtual environments on your computer with it, and then use it to install packages into the system when using a container.
Here is an example Dockerfile as a starting point:
FROM python:3.12-slim
# Set up the Python production environment
WORKDIR /app
COPY Pipfile Pipfile.lock ./
RUN python -m pip install --upgrade pip pipenv && \
pipenv install --system --deploy
This will install your Python dependencies into the system so that you don’t have to mess with virtual environments inside of a Docker container, because the container is your virtual environment. Additionally the Pipfile.lock will ensure that the same dependency versions in your development environment, get install into your production environment. The uv tool also creates a uv.lock file which serves the same purpose.