Деплой FastAPI-приложения через Docker Compose
FastAPI удобно паковать в контейнер и запускать через Compose — так приложение, его зависимости и прокси описаны декларативно и переезжают на любой сервер одной командой.
Dockerfile
Берём slim-образ Python, ставим зависимости отдельным слоем (чтобы кешировались), затем копируем код:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ app/
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml
Поднимаем приложение и Caddy. Приложение не публикует порт наружу (только expose внутри сети Compose), а наружу смотрит прокси:
services:
app:
build: .
restart: unless-stopped
expose: ["8000"]
env_file: [.env]
volumes:
- data:/app/data
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports: ["80:80", "443:443"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
volumes:
data:
caddy_data:
Сборка и запуск
Дальше всё в две команды. При неизменном requirements.txt слой с pip берётся из кеша, поэтому пересборка после правки кода занимает секунды:
docker compose build app
docker compose up -d app
Логи смотрим через docker compose logs -f app, состояние — docker compose ps. Данные переживают пересоздание контейнера, потому что лежат в именованном томе data.