Почему Python не может найти необходимые модули после «установки pip» внутри образа Docker?

У меня проблема с Python: он не может найти никаких зависимостей при работе в контейнере. В моем случае у меня есть приложение на основе fastAPI, которое прекрасно работает на моем локальном компьютере. Когда я запускаю образ докера, он жалуется на каждый отдельный модуль, пока я не выполняю отдельную «pip install xyz» внутри образа.

У меня есть следующий Dockerfile:

# Use the official Python image from the Docker Hub
FROM python:3.12-slim as builder

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Install build dependencies
RUN apt-get update \
    && apt-get install -y --no-install-recommends gcc libpq-dev

# Create a working directory
WORKDIR /app

# Install pipenv and python dependencies in a virtual environment
COPY ./requirements.txt /app/
RUN python3 -m venv venv && bash -c "source venv/bin/activate"
RUN venv/bin/pip3 install -r requirements.txt

# Use the official Python image again for the final stage
FROM python:3.12-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Create a working directory
WORKDIR /app

# Copy installed dependencies from the builder stage
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=builder /usr/local/bin/pip /usr/local/bin/pip

# Copy the application code
COPY . /app

# Install runtime dependencies (if any)
RUN pip install uvicorn gunicorn

# Expose the port the app runs on
EXPOSE 8000

# Command to run the application
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8000", "--workers", "4"]

Мой файл require.txt содержит все необходимые модули, например

...
fastapi==0.111.0
fastapi-cli==0.0.4
filelock==3.14.0
...
pydub==0.25.1
Pygments==2.18.0
python-dotenv==1.0.1
python-multipart==0.0.9
PyYAML==6.0.1
requests==2.32.3
rich==13.7.1
...

Я построил контейнер с:

docker build -t my-fastapi-app.

Я запускаю контейнер с помощью:

docker run -p 8000:8000 мое-фастапи-приложение

он печатает длинный стек вызовов, заканчивающийся:

ModuleNotFoundError: No module named 'requests'

Затем я собираюсь добавить модули с помощью отдельной «pip install» внутри Dockerfile:

RUN pip install pydub requests

Теперь он жалуется на отсутствие fastAPI:

ModuleNotFoundError: No module named 'fastapi'

Итак, я собираюсь добавить еще один pip install с fastAPI и так далее и тому подобное.

Затем я попробовал использовать Pipenv:

COPY ./Pipfile /app
COPY ./Pipfile.lock /app

RUN pip install --upgrade pip \
    && pip install pipenv \
    && pipenv install --deploy --ignore-pipfile

Необходимый Pipfile содержит все необходимые модули, но после установки они все равно отсутствуют.

Я думал, что pip install -r requirements.txt сделает все это автоматически. Но здесь дело не в этом. Где моя ошибка?

Нужно ли мне взрывать свой Dockerfile отдельными командами «pip install» для всех модулей, перечисленных в моем «requirements.txt»?

Или виртуальная среда просто каким-то образом испорчена, и Python не может найти какие-либо модули, хотя они установлены?

🤔 А знаете ли вы, что...
С Python можно создавать кросс-платформенные приложения для Windows, macOS и Linux.


53
1

Ответ:

Решено

Вы устанавливаете что-то в виртуальную среду, а затем копируете каталог системных пакетов (в котором тогда нет этих deps) в контейнер времени выполнения.

Вместо этого скопируйте virtualenv (а затем используйте его).

RUN python3 -m venv /venv
RUN /venv/bin/pip3 install -r requirements.txt

# Use the official Python image again for the final stage
FROM python:3.12-slim
# ...
COPY --from=builder /venv /venv
# ...
RUN /venv/bin/python -m pip install uvicorn gunicorn
# ...
CMD ["/venv/bin/gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8000", "--workers", "4"]

Интересные вопросы для изучения