Развертывание 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
и т. д. понятия не имеет об их существовании.
Есть как минимум два возможных решения:
Заставьте 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
.)Альтернативный вариант, поскольку
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.