Как запустить приложение FastAPI с использованием многослойной сборки и менеджера зависимостей pdm?

Вопрос или проблема

Как запустить приложение FastAPI с использованием многослойной сборки и менеджера зависимостей pdm?

Я пытаюсь запустить приложение FastAPI, используя pdm и следующий Dockerfile:

ARG PYTHON_BASE=3.10-slim

# Этап сборки
FROM python:$PYTHON_BASE as build

COPY pyproject.toml pdm.lock README.md ./

# Установка pdm
RUN python -m pip install --upgrade pip setuptools wheel &&\
    pip install pdm

# Установка зависимостей
RUN pdm install --no-lock --no-editable


# Этап выполнения
FROM python:$PYTHON_BASE

# Копирование файлов приложения
COPY src /src
COPY logging_config.yaml .

COPY --from=build /.venv /.venv
ENV PATH="/.venv/bin:{$PATH}"

EXPOSE 5000

CMD ["uvicorn", "src.backend.main:app", "--host", "0.0.0.0", "--port", "5000"]

Структура моего проекта следующая:

backend
|- src/backend
|  |- main.py
|- Dockerfile
|- pdm.lock
|- pyproject.toml
|- README.md

Я получаю следующую ошибку после выполнения команд для сборки образа и запуска контейнера:

sudo docker build -t backend:v0.1.0 .
sudo docker run -p 5000:5000 backend:v0.1.0

Ошибка:
exec /.venv/bin/uvicorn: нет такого файла или директории

Может кто-то объяснить, как правильно настроить контейнер?

Сначала я подумал, что контейнер не может найти путь к виртуальному окружению для uvicorn, поэтому я зашел в bash контейнера, что дало результат:

docker run -it backend:v0.1.0 /bin/bash
which uvicorn
>>> /.venv/bin/uvicorn

Мне удалось выявить проблему. Похоже, я инициализировал проект pdm с помощью Python 3.12, в то время как пытался развернуть приложение, используя Python 3.10. Это несоответствие привело к тому, что контейнер искал venv для 3.10, в то время как создавался 3.12. Поэтому я просто обновил базовый образ на python:3.12-slim, и Dockerfile заработал как есть.

Ответ или решение

Для того чтобы правильно запустить приложение FastAPI на базе Docker с использованием pdm в качестве менеджера зависимостей в многослойной сборке, необходимо учитывать несколько ключевых аспектов. Давайте разберем ваш сценарий и предложим правильное решение.

Проблема и Решение

Ваша проблема заключалась в несоответствии версий Python, используемых в проекте и в Docker-контейнере. Вы инициализировали проект с помощью Python 3.12, но попытались развернуть его с использованием Python 3.10. Это приводит к ошибкам, так как pdm создает виртуальную среду для версии Python 3.12, однако Docker пытается запускать uvicorn из виртуальной среды Python 3.10.

Исправленный Dockerfile

Измените ваш Dockerfile, чтобы обеспечить согласованность версий Python:

ARG PYTHON_BASE=3.12-slim

# Студия сборки
FROM python:$PYTHON_BASE as build

COPY pyproject.toml pdm.lock README.md ./

# Установка pdm
RUN python -m pip install --upgrade pip setuptools wheel && \
    pip install pdm

# Установка зависимостей
RUN pdm install --no-lock --no-editable

# Исполняемая стадия
FROM python:$PYTHON_BASE

# Копирование файлов приложения
COPY src /src
COPY logging_config.yaml .

COPY --from=build /.venv /.venv
ENV PATH="/.venv/bin:$PATH"

EXPOSE 5000

CMD ["uvicorn", "src.backend.main:app", "--host", "0.0.0.0", "--port", "5000"]

Объяснение

  1. Версия Python: Изменена версия базового образа на python:3.12-slim для согласованности с версией Python, используемой в pdm.

  2. Копирование и установка зависимостей: Сначала происходит установка зависимостей в стадии сборки, затем копируется виртуальная среда в окончательный образ.

  3. Настройка PATH: Путь к виртуальной среде правильно добавлен в переменную окружения PATH, что обеспечит доступ к исполняемым файлам, установленным в виртуальной среде.

  4. Запуск FastAPI: Используется команда uvicorn для запуска приложения, указывая корректный путь к вашему приложению FastAPI.

Построение и Запуск

Для сборки и запуска контейнера выполните команды:

sudo docker build -t backend:v0.1.0 .
sudo docker run -p 5000:5000 backend:v0.1.0

Заключение

С обновленной версией Python в Docker вы сможете избежать проблем, связанных с несовпадением версий. Следите за тем, чтобы версии локального окружения и окружения в Docker совпадали, чтобы избежать подобных ошибок в будущем. Если вы будете следовать этим шагам, ваше приложение FastAPI должно успешно запуститься в контейнере.

Оцените материал
Добавить комментарий

Капча загружается...