7 октября 2026 г.
FastAPI Production Checklist
Что проверить перед выкладкой FastAPI в прод.
Запустить FastAPI локально — легко. Запустить его в продакшене так, чтобы он не падал, не тормозил и не терял данные — это отдельная работа. Ниже — чек-лист, который я использую перед каждым релизом. Он не претендует на истину в последней инстанции, но покрывает 90% проблем, с которыми я сталкивался.
Наблюдаемость
Без наблюдаемости вы не знаете, что происходит с приложением. Логи, метрики, трейсы — три столпа.
Логи
Что важно:
- Структурированные логи (JSON), а не
print(). - Уровни:
DEBUG,INFO,WARNING,ERROR,CRITICAL. - Correlation ID — чтобы связать логи одного запроса.
- Ротация — чтобы не забили диск.
Пример с structlog:
import structlog
logger = structlog.get_logger()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
logger.info("fetching_user", user_id=user_id)
user = await db.get(User, user_id)
if not user:
logger.warning("user_not_found", user_id=user_id)
raise HTTPException(404)
return user
Безопасность
Безопасность — не опция и не «потом добавим». Даже пет-проект могут взломать, а портфолио — тем более. Ниже — три вещи, которые закрывают 80% проблем: CORS, rate limiting, JWT.
CORS
Что это. Механизм, который говорит браузеру, с каких доменов можно обращаться к твоему API. Если настроить неправильно — либо всё открыто, либо всё сломано.
Что важно:
- Разрешать только свои домены.
- Не использовать allow_origins=["*"] в продакшене.
- Ограничить методы и заголовки.
- Не сочетать allow_origins=["*"] с allow_credentials=True — это несовместимо.
Пример:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://mydomain.com", "https://www.mydomain.com"],
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["*"],
)
Rate Limiting
Что это. Ограничение количества запросов с одного IP или от одного пользователя. Защищает от брутфорса, спама и DDoS.
Что важно:
- Разные лимиты для разных эндпоинтов.
- Лимит на IP и на пользователя.
- Хранить счётчики в Redis, а не в памяти.
- Отдавать 429 Too Many Requests с заголовком Retry-After.
Пример с slowapi:
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
@app.get("/login")
@limiter.limit("5/minute")
async def login(request: Request):
...
Что лимитировать:
- Логин — 5/мин.
- Регистрация — 3/час.
- API — 100/мин.
- Тяжёлые запросы — 10/мин.
- Пароль-ресет — 3/час.
База данных
База — сердце приложения. Если она упадёт или потеряет данные, всё остальное уже не важно. Ниже — два столпа: миграции и бэкапы. Плюс немного про пул соединений и индексы, потому что без них база тормозит.
Миграции Alembic
Что это. Alembic — инструмент для управления изменениями схемы БД. Каждое изменение — отдельная миграция, которую можно применить или откатить.
Что важно:
- Все изменения схемы — только через миграции.
- Не менять БД вручную.
- Проверять миграции на тестовой БД.
- Хранить миграции в git.
- Писать downgrade, а не только upgrade.
- Не редактировать применённые миграции.
Пример:
# Создать миграцию
alembic revision --autogenerate -m "add users table"
# Применить все миграции
alembic upgrade head
# Применить одну
alembic upgrade +1
# Откатить одну
alembic downgrade -1
# Откатить всё
alembic downgrade base
# Посмотреть текущую версию
alembic current
# Посмотреть историю
alembic history
Пример миграции:
"""add users table
Revision ID: abc123
Revises:
Create Date: 2026-01-01 12:00:00
"""
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
"users",
sa.Column("id", sa.Integer, primary_key=True),
sa.Column("email", sa.String(255), unique=True, nullable=False),
sa.Column("created_at", sa.DateTime, server_default=sa.func.now()),
)
op.create_index("ix_users_email", "users", ["email"])
def downgrade():
op.drop_index("ix_users_email", table_name="users")
op.drop_table("users")
Бэкапы (Резервные копии)
Что это. Регулярные копии БД, которые позволяют восстановиться после сбоя, ошибки или атаки.
Что важно:
- Ежедневно.
- В разные места (S3, другой сервер).
- Проверять восстановление.
- Шифровать.
- Хранить минимум 30 дней.
- Автоматизировать.
Примери скрипта для резервого копирования:
#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_${DATE}.sql.gz"
# Создать бэкап
pg_dump -U user -h localhost dbname | gzip > /backups/${BACKUP_FILE}
# Загрузить в S3
aws s3 cp /backups/${BACKUP_FILE} s3://my-backups/
# Удалить старые (старше 30 дней)
find /backups -name "backup_*.sql.gz" -mtime +30 -delete