Докеризация FastAPI

6 сентября 2024 г.

Источник: тут

  1. Создаём Dockerfile (базовый для Python)

    # клонировать официальный образ Python
    FROM python:3.11.1-slim
    
    # задать рабочую директорию
    WORKDIR /app
    
    # задаются значения переменных окружения
    ENV PYTHONDONTWRITEBYTECODE 1
    # чтобы Python не создавал скомпилированные файлы для ускорения запуска
    ENV PYTHONUNBUFFERED 1
    # чтобы Python не использовал буферизацию ввода-вывода
    
    # установить зависимости
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    
    # скопировать проект
    COPY . .
  2. Добавляем docker-compose.yml (ссылка на документацию)

    version: '3.8'
    services:
      web:
        build: .
        command: uvicorn app.main:app --host 0.0.0.0
        # можно добавить ожидание postgres: bash -c 'while !</dev/tcp/db/5432; do sleep 1; done; 
        volumes:
          - .:/app
        ports:
          - 8008:8000
        environment:
          - DATABASE_UR=postgresql://postgres:postgres@db:5432/postgres
      # можно добавлять другие сервисы, например:
      db:
        image: postgres:13.3
        volumes:
          - ./db_data:/var/lib/postgresql/data
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: postgres
        expose:
          - 5432 # для отладки через DBeaver
        # аналог:
        ports:
          - 5432:5432
    

    Для ORM можно выбрать любую: mjhea0/awesome-fastapi - Databases

  3. Добавляем получение переменных окружения:

    import os
    
    from pydantic import BaseSettings, Field
    
    
    class Settings(BaseSettings):
        db_url: str = Field(..., env='DATABASE_URL')
    
    settings = Settings()
  4. Собираем контейнер

    docker-compose build
  5. Запускаем контейнер

    docker-compose up -d

    Ключ -d запускает контейнер в фоновом режиме.

  6. Проверяем работу контейнера: перейдите на localhost:8008.

    Если не работает, то запустите команду отображения логов:

    docker-compose logs -f
  7. Останавливаем контейнер

    docker-compose down -v
  8. Dockerfile.prod

    FROM tiangolo/uvicorn-gunicorn:python3.11-slim
    
    RUN apt-get update && apt-get install -y netcat
    
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    
    COPY . .
  9. prestart.sh - команда для ожидания Postgres

    echo "Waiting for postgres connection"
    
    while ! nc -z db 5432; do
        sleep 0.1
    done
    
    echo "PostgreSQL started"
    
    exec "$@"
  10. Обновить разрешения:

    chmod +x prestart.sh
  11. docker-compose.prod.yml

    version: '3.8'
    
    services:
      web:
        build:
          context: .
          dockerfile: Dockerfile.prod
        ports:
          - 8009:80
        environment:
          - DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
        depends_on:
          - db
      db:
        image: postgres:15-alpine
        volumes:
          - postgres_data_prod:/var/lib/postgresql/data/
        expose:
          - 5432
        environment:
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=postgres
          - POSTGRES_DB=postgres
    
    volumes:
      postgres_data_prod:
  12. Пробуем!

    docker-compose -f docker-compose.prod.yml up -d --build
  13. Добавляем Traefik.

    скоро будет