I'm using Docker
and build a custom image. I base my image on a Debian
distribution and add some packages with a requirements.txt
file. When I build the Docker
image, I can see packages installation in the log, but when I run it I can't use additionals packages from requirements.txt
because the're not installed.
Is it link with --break-system-packages
options ?
Because if i don't precise it, I have error: externally-managed-environment
Dockerfile
FROM debian:latest
# Setting code directory
WORKDIR /code
# Install pip
RUN set -xe \
&& apt-get update -y \
&& apt-get install -y pip
RUN pip install --upgrade pip --break-system-packages
# Install requirements
COPY requirements.txt .
RUN pip install -r requirements.txt --break-system-packages
requirements.txt
nano
psycopg2-binary
pandas
Build image
docker build --network=host -t "debian:latest" .
Run it
docker run -it --entrypoint /bin/sh debian
Search packages (no results)
dpkg --list | grep -i -e nano -e pandas -e psycopg
There are several issues in the Dockerfile setup you show. It seems like you're mixing operating-system packages (managed by dpkg
) and Python packages (managed by pip
) and this is causing some confusion.
Outside of Docker, I'd start by creating the requirements.lock
file with the exact Python versions you need. The Python Packaging User Guide describes some options around tooling. For example purposes, I'll use a plain Python virtual environment:
python -m venv ./venv
. ./venv/bin/activate
pip install psycopg2-binary pandas
pip freeze > requirements.txt
In your Docker setup, I'd suggest starting from a python
base image. This gives you more control over what exact version of Python is in use, and comes with some tools like pip
preinstalled. (You may have specific requirements in your local organization to build an image from a known starting point, in which case you should have guidance on how to get common language runtimes like this.)
Once you have installed the application's Python-level dependencies, don't forget to also copy in your code, and to set a default CMD
for the container to run.
Put together, this might look like
FROM python:3.11
WORKDIR /code
# Copy the frozen requirements file in and install those packages.
# Use the "system" Python inside the isolated images.
# Do this separately to improve performance on rebuild.
COPY requirements.txt ./
RUN pip install -r requirements.txt
# Copy the rest of the application in.
COPY ./ ./
# Set the default command to run when you launch the container.
CMD ["./myapp.py"]
Your Python code should be able to import
modules from the packages you installed using pip install
.
The default python
image happens to be Debian-based, but the Debian package management system (the dpkg
tool and the higher-level APT wrapper) are separate from the Python packaging system. Things you pip install
won't be visible with dpkg --list
. If a Python library has a Debian package then in principle you can apt-get install libpython-...
, but this isn't a typical Docker-based workflow.