KNOTTA research & development

Деплой

Ansible-плейбук, порядок ролей, секреты, сервисные хуки.

Деплой

Прод-окружение разворачивается через Ansible на одном хосте. Все сервисы — Docker-контейнеры в общей сети ng_metrics.

Главный плейбук

ansible/playbooks/prod/ng-metrics.yaml — единая точка деплоя.

cd ansible
poetry install
poetry run ansible-playbook -i inventory/prod playbooks/prod/ng-metrics.yaml

При запуске спросит GitHub-токен (для скачивания приватных репозиториев и контейнеров).

Порядок ролей

Загрузка диаграммы…
РольЧто делаетСтатус
infisicalПолучает все секреты по проекту и окружениюактивна
commonНастройка хоста, swap, Docker, базовые пакетыактивна
supabaseПоднимает Supabase (PostgreSQL, Auth, Storage), деплоит Edge Functions, заливает бренд-ассетыактивна
systemСоздаёт Docker-сеть ng_metrics, поднимает Redis, конфигурирует Traefik (HTTPS + reverse proxy)активна
ng-metrics-backendДва контейнера: web (Django + gunicorn на :7000) и worker (celery -A ng_metrics worker). Воркер использует тот же образ; entrypoint очищен, чтобы не запускать миграции и gunicorn. Concurrency задаётся переменной celery_worker_concurrency (default 2).активна
ng-metrics-frontendNext.js на :3000активна
ng-metrics-botTelegram-бот на :8080отключена
chatwootПлатформа поддержкиотключена

Секреты — Infisical

Все секреты живут в Infisical (self-hosted). Структура:

ПроектОкружение
ng-metricsprod / staging

Ключевые переменные (без значений — чтобы не утекли в git):

ГруппаПеременные
SupabaseSUPABASE_URL, SUPABASE_EXTERNAL_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_JWT_SECRET
PostgresPOSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT
ResendRESEND_API_KEY, RESEND_FROM_EMAIL, RESEND_WEBHOOK_SECRET
TelegramTELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET
ChatwootCHATWOOT_URL, CHATWOOT_API_KEY, CHATWOOT_WEBHOOK_SECRET
DjangoSECRET_KEY, ALLOWED_HOSTS, DASHBOARD_APP_PUBLIC_URL
Redis / CeleryREDIS_HOST, REDIS_PORT, REDIS_PASSWORD. URL'ы для брокера (DB 3) и result-backend (DB 4) собираются автоматически в settings/production.py.

Локально секреты лежат в .env.local каждого сервиса (есть .env.example как шаблон).

Redis — разделение по базам

Один Redis-инстанс, пять баз:

DBСервисЧто хранит
0GardenRedis Stream для уведомлений в Telegram, кэш
1ChatwootОчереди, sidekiq
2BotFSM-состояния Aiogram, сессии Chatwoot
3Garden / CeleryBroker для фоновых задач (отправка уведомлений)
4Garden / CeleryResult backend

DB 3 и 4 добавлены в апреле 2026 вместе с Celery-воркером.

Reverse proxy и HTTPS

Перед всеми сервисами — Traefik (HTTPS terminator + reverse proxy + автоматические сертификаты Let's Encrypt). С апреля 2026 он заменил связку Caddy + Nginx — теперь это единая точка входа.

internet → Traefik (:80 → :443)
   ├─ knotta.ru → frontend:3000
   ├─ api-knotta.ru → backend:7000
   └─ service-knotta.ru → supabase-kong:8000

Traefik сам получает сертификаты Let's Encrypt по HTTP-01 challenge. Конфигурация:

  • Статическая — ansible/roles/system/templates/traefik.yaml.j2 (entry points, ACME-резолвер, providers).
  • Динамическая (роутеры и сервисы) — ansible/roles/system/templates/traefik-dynamic.yaml.j2.
  • Хранилище ACME-сертификатов — volumes/traefik/acme.json на хосте.

Все сервисы за Traefik подключаются через статические маршруты в динамическом конфиге (file provider, без Docker labels).

Edge Functions

Деплой Supabase Edge Functions — внутри роли supabase:

supabase functions deploy send-email
supabase functions deploy auth-sync
supabase functions deploy set-role

Это делается роль автоматически через supabase CLI.

Важно: после деплоя нужно проверить, что в Supabase Studio (Authentication → Settings → Hooks) URL хука send-email указывает на актуальную Edge Function.

Миграции БД

Миграции применяются автоматически при деплое ng-metrics-backend — таска роли запускает python manage.py migrate внутри контейнера до старта DRF-сервера.

Не запускайте миграции вручную в проде — это сломает контейнерную жизнь backend'а. Если миграция большая — добавьте её в roadmap отдельной задачей и применяйте в техническое окно.

Healthchecks

СервисHealthcheck URL
FrontendGET / (200)
BackendGET /api/schema/ (200)
BotGET /health (200)
SupabaseGET /rest/v1/ с anon-ключом (200)

Traefik и Docker используют их для restart-логики и для проверки live-ness апстримов.

Откат деплоя

# Назад к предыдущему контейнеру
poetry run ansible-playbook \
    -i inventory/prod \
    playbooks/prod/rollback.yaml \
    --extra-vars "service=ng-metrics-backend version=v1.4.0"

История версий — теги Docker-образов (создаются по тегам git).

Настройка нового окружения

  1. Создать инвентарь в ansible/inventory/<env>/.
  2. Положить group_vars/all/vault.yaml (зашифрован через ansible-vault).
  3. В Infisical создать соответствующее окружение и заполнить переменные.
  4. В Supabase создать проект, прокинуть SUPABASE_* в Infisical.
  5. Запустить плейбук на новом хосте.
  6. После старта — создать суперпользователя:
docker exec -it ng-metrics-backend python manage.py createsuperuser

CI/CD

CI лежит в каждом репозитории отдельно (.github/workflows/):

  • Frontend — линт, проверка типов, тесты, билд.
  • Backend — линт, mypy, pytest.
  • Bot — линт, mypy.

CD на текущем этапе ручной — деплой запускается с локальной машины DevOps через Ansible. В roadmap — переход на push-driven деплой через GitHub Actions + self-hosted runner.

Журнал инцидентов

Инциденты и крупные изменения деплоя описываются в Истории изменений. Полные технические детали последнего крупного релиза — в docs/modification-april-2026/system-design.md.

На странице