# M7: упаковка в docker-compose — API, PostgreSQL, фронт (nginx).
# TLS терминирует внешний reverse-proxy на VPS (контейнер web — :80 за ним).
# Ollama — внешний сервер, адрес в .env (OLLAMA_BASE_URL), модель — OLLAMA_MODEL.
# Настройки читаются из .env в корне репо (шаблон — .env.example).
services:
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-gntodo}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-gntodo}
POSTGRES_DB: ${POSTGRES_DB:-gntodo}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-gntodo}"]
interval: 5s
timeout: 3s
retries: 12
api:
build: ./backend
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-gntodo}:${POSTGRES_PASSWORD:-gntodo}@db:5432/${POSTGRES_DB:-gntodo}
GAUTH_BASE_URL: ${GAUTH_BASE_URL}
GAUTH_CLIENT_ID: ${GAUTH_CLIENT_ID}
GAUTH_CLIENT_SECRET: ${GAUTH_CLIENT_SECRET}
GAUTH_REDIRECT_URI: ${GAUTH_REDIRECT_URI}
SESSION_SECRET: ${SESSION_SECRET}
OLLAMA_BASE_URL: ${OLLAMA_BASE_URL}
OLLAMA_MODEL: ${OLLAMA_MODEL:-qwen3.5:2b-q4_K_M}
MCP_TOKEN: ${MCP_TOKEN:-}
ATTACHMENTS_PATH: /data/attachments
volumes:
- attachments:/data/attachments
expose:
- "8134"
healthcheck:
# CMD контейнера сначала гоняет миграции — даём запас на старт
test: ["CMD", "python", "-c", "import urllib.request as u; u.urlopen('http://localhost:8134/api/health')"]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
web:
build: ./frontend
restart: unless-stopped
depends_on:
- api
ports:
- "${WEB_PORT:-8135}:80"
volumes:
pgdata:
attachments: