Skip to content

Instantly share code, notes, and snippets.

@Eugene-Fed
Created March 24, 2025 15:39
Show Gist options
  • Select an option

  • Save Eugene-Fed/59ccea19bbbb968555e12fd06e2fea32 to your computer and use it in GitHub Desktop.

Select an option

Save Eugene-Fed/59ccea19bbbb968555e12fd06e2fea32 to your computer and use it in GitHub Desktop.

Для интеграции Gunicorn с FastAPI необходимо настроить веб-сервер, который будет управлять процессами и обрабатывать HTTP-запросы. Gunicorn часто используется для запуска асинхронных приложений в продакшене, так как позволяет эффективно масштабировать нагрузку. Вот пошаговое руководство:


1. Установка зависимостей

pip install fastapi gunicorn uvicorn

2. Базовая конфигурация

2.1 Запуск через командную строку

Пример запуска FastAPI через Gunicorn:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
  • -w 4: Количество worker-процессов (рекомендуется workers = 2 * CPU_CORES + 1).
  • -k uvicorn.workers.UvicornWorker: Указание асинхронного worker'а для FastAPI.

3. Примеры конфигураций

3.1 Простой запуск

gunicorn main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  --timeout 120

3.2 Использование конфигурационного файла

Создайте файл gunicorn.conf.py:

bind = "0.0.0.0:8000"
workers = 4
worker_class = "uvicorn.workers.UvicornWorker"
timeout = 120
accesslog = "-"
errorlog = "-"
loglevel = "info"

Запуск:

gunicorn -c gunicorn.conf.py main:app

4. Продакшен-настройки

4.1 Рекомендуемые параметры

gunicorn main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  --access-logfile - \
  --error-logfile - \
  --timeout 120 \
  --keepalive 120 \
  --log-level info \
  --capture-output \
  --enable-lookup

4.2 Настройка через переменные окружения

export APP_MODULE=main:app
export WORKERS=4
export PORT=8000

gunicorn $APP_MODULE \
  --workers $WORKERS \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:$PORT

5. Интеграция с Nginx

5.1 Конфигурация Nginx

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

6. Интеграция с systemd

6.1 Создание сервиса

Создайте файл /etc/systemd/system/fastapi.service:

[Unit]
Description=FastAPI with Gunicorn
After=network.target

[Service]
User=your_user
Group=www-data
WorkingDirectory=/path/to/your/project
ExecStart=/usr/bin/gunicorn -c /path/to/gunicorn.conf.py main:app
Restart=on-failure
KillMode=mixed
TimeoutStopSec=20
PrivateTmp=true

[Install]
WantedBy=multi-user.target

6.2 Запуск сервиса

sudo systemctl daemon-reload
sudo systemctl enable --now fastapi.service

7. Асинхронность и workers

7.1 Выбор worker'а

Для FastAPI (основанного на ASGI) используйте uvicorn.workers.UvicornWorker, так как стандартные worker'ы Gunicorn не поддерживают асинхронность:

gunicorn ... -k uvicorn.workers.UvicornWorker

7.2 Количество workers

# В gunicorn.conf.py
import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1

8. Логирование

8.1 Настройка логов

gunicorn ... \
  --access-logfile /var/log/gunicorn/access.log \
  --error-logfile /var/log/gunicorn/error.log \
  --log-level debug

8.2 JSON-логирование

Создайте файл logging.conf:

[loggers]
keys=root,gunicorn.error,gunicorn.access

[handlers]
keys=consoleRotatingFileHandler

[formatters]
keys=json_formatter

[logger_root]
level=INFO
handlers=consoleRotatingFileHandler

[logger_gunicorn.error]
level=INFO
handlers=consoleRotatingFileHandler
qualname=gunicorn.error
propagate=0

[logger_gunicorn.access]
level=INFO
handlers=consoleRotatingFileHandler
qualname=gunicorn.access
propagate=0

[handler_consoleRotatingFileHandler]
class=logging.handlers.RotatingFileHandler
formatter=json_formatter
args=("/var/log/gunicorn/app.log", "a", 5000000, 5)

[formatter_json_formatter]
format = %(asctime)s [%(process)d] [%(levelname)s] %(message)s
datefmt = %Y-%m-%d %H:%M:%S
class = pythonjsonlogger.jsonlogger.JsonFormatter

9. Интеграция с Docker

9.1 Dockerfile

FROM python:3.9-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["gunicorn", "-c", "gunicorn.conf.py", "main:app"]

9.2 docker-compose.yml

version: '3.8'
services:
  api:
    build: .
    ports:
      - "8000:8000"
    environment:
      - WORKERS=4
    depends_on:
      - db

10. Примеры конфигураций

10.1 Конфигурация для высокой нагрузки

# gunicorn.conf.py
bind = "0.0.0.0:8000"
workers = 8
worker_class = "uvicorn.workers.UvicornWorker"
threads = 2
timeout = 120
keepalive = 2
accesslog = "/var/log/gunicorn/access.log"
errorlog = "/var/log/gunicorn/error.log"
loglevel = "info"

10.2 Асинхронный режим

gunicorn main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000

11. Бест-практисы

11.1 Управление worker'ами

  • Для асинхронных приложений используйте uvicorn.workers.UvicornWorker.
  • Избегайте sync worker'ов (например, sync или gevent).

11.2 Настройка параметров

  • --timeout: Установите разумное значение (например, 120 секунд).
  • --preload: Загрузка приложения до запуска worker'ов (полезно для обработки сигналов).
  • --graceful-timeout: Время ожидания завершения worker'а при перезагрузке.

11.3 Безопасность

  • Избегайте запуска Gunicorn как root.
  • Используйте Nginx для внешнего доступа и SSL-терминации.

12. Пример полного приложения

12.1 main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello World"}

12.2 gunicorn.conf.py

bind = "0.0.0.0:8000"
workers = 4
worker_class = "uvicorn.workers.UvicornWorker"
accesslog = "-"
errorlog = "-"
loglevel = "info"

13. Решение проблем

13.1 Ошибка "No application found"

Убедитесь, что путь к приложению указан правильно (например, main:app).

13.2 Асинхронность

Если используется асинхронный код, обязательно используйте UvicornWorker:

gunicorn -k uvicorn.workers.UvicornWorker ...

13.3 Таймауты

Для долгих задач увеличьте timeout:

gunicorn ... --timeout 300

14. Примеры команд

14.1 Запуск с динамическим количеством workers

gunicorn main:app \
  --workers $(($(nproc)*2+1)) \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000

14.2 Запуск с reload

gunicorn main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  --reload

15. Библиотеки и инструменты

  • uvicorn: Для асинхронных worker'ов.
  • gunicorn: Основной веб-сервер.
  • systemd: Для управления сервисами в Linux.

16. Итоговые рекомендации

Для работы с Gunicorn в FastAPI:

  1. Используйте uvicorn.workers.UvicornWorker для асинхронности.
  2. Настройте количество workers в зависимости от количества CPU.
  3. Интегрируйте с Nginx для внешнего доступа и SSL.
  4. Используйте systemd для автозапуска и мониторинга.
  5. Настройте логирование для отслеживания ошибок и производительности.

Это обеспечит стабильный и масштабируемый запуск вашего FastAPI приложения.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment