Search code examples
dockerpipdebian

Dockerfile - Use extra packages from requirements.txt


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

Solution

  • 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.