Развертывание Heroku с помощью docker и поэзии

Я пытаюсь развернуть приложение django на heroku. Я использую docker и poetry. У меня возникла проблема, потому что в докерфайле я устанавливаю поэзию и устанавливаю зависимости с помощью поэзии. Локально все работает нормально, но когда я хочу развернуть приложение на heroku, зависимости не устанавливаются. Устанавливается только код типа:

"RUN pip install -r requirements.txt" устанавливает зависимости на heroku (я создал файл requirements.txt с помощью экспорта поэзии).

Нужно

ли мне иметь два разных Dockerfiles для dev и prod, где я буду использовать стихи в одном и pip install requirements в другом? Или я должен использовать многоступенчатый Dockerfile, или у вас есть другие предложения?

Мой Dockerfile с potery:

FROM python:3.11-alpine

WORKDIR /code

ENV PYTHONUNBUFFERED 1
ENV PATH "/root/.local/bin:$PATH"

RUN apk add --no-cache curl \
    && curl -sSL https://install.python-poetry.org | python3 - \
    && apk add --no-cache postgresql-dev musl-dev

COPY poetry.lock pyproject.toml /code/

RUN poetry install --no-root

COPY . /code/

RUN poetry install

heroku.yml:

build:
  docker:
    web: backend/Dockerfile

run:
  web: gunicorn core.wsgi:application --bind 0.0.0.0:$PORT

Вывод из развертывания:

У меня сейчас нет диноскопа Heroku для тестирования, но я считаю, что вас кусает это:

Мы настоятельно рекомендуем тестировать образы локально от имени пользователя, не являющегося root, поскольку контейнеры в Heroku не запускаются с правами root.

(Далее в документации объясняется, как это сделать, но я не буду копировать ее сюда, так как это немного в сторону.)

Поскольку Poetry по умолчанию создает виртуальное окружение, именно туда попадают ваши зависимости. Система python, pip и т. д. понятия не имеет об их существовании.

Есть как минимум два возможных решения:

  1. Заставьте Poetry устанавливать пакеты в системное окружение Python, отключив его virtualenvs.create настройку (выделено автором):

    Если установлено значение false, Poetry не будет создавать новую виртуальную среду. Если он обнаружит уже включенное виртуальное окружение или существующее в {cache-dir}/virtualenvs или {project-dir}/.venv, он установит зависимости в них, в противном случае он установит зависимости в системное окружение python.

    Один из способов сделать это - добавить новую команду RUN или подключить ее к существующей, где вы запускаете poetry install:

    RUN poetry config virtualenvs.create false && poetry install
    #   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    (Примечание: я не думаю, что вам нужно запускать poetry install дважды. Вы должны быть в состоянии избавиться от одного с помощью --no-root перед командой COPY.)

  2. Альтернативный вариант, поскольку heroku run poetry show показывает ваши зависимости¹, вы можете попробовать префикс вашего web процесса с poetry run:

    run:
      web: poetry run gunicorn core.wsgi:application --bind 0.0.0.0:$PORT
      #    ^^^^^^^^^^
    

В любом случае, вам не нужно генерировать requirements.txt. Его наличие рядом с файлами Poetry сбивает с толку, и это еще одна вещь, которую нужно поддерживать. Я предлагаю удалить его совсем.


¹ Я удивлен, что это так. Обычно непривилегированный пользователь не имеет доступа ни к чему в /root/, а именно там я ожидал бы, что Poetry установит зависимости при запуске пользователем root.

Вернуться на верх