DispelEvilBot/DEPLOY.md

149 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Развёртывание
Клонируем репозиторий и поднимаем контур Compose-ом. Контуры `test` и `prod`
разделяются именем проекта (`-p`) и файлом окружения (`--env-file`) — у каждого
свои БД и volume'ы, на одной машине не пересекаются.
## 1. Клонировать
```bash
git clone ssh://git@<gitea-host>:2222/mpakobecex/DispelEvilBot.git
cd DispelEvilBot
```
## 2. Подготовить окружение
```bash
cp env/test.env.example env/test.env
# заполнить: BOT_TOKEN, DB_PASSWORD, CHAT_ID (основной чат), ALERT_CHAT_ID (опц.),
# ADMIN_IDS (опц.), CLICKHOUSE_PASSWORD (аналитика событий)
```
Порт ClickHouse на хосте (`CLICKHOUSE_HTTP_PORT`) у контуров должен различаться:
`prod` — `8123`, `test` — `8124` (иначе контейнеры конфликтуют на одной VPS).
## 3. Логин в registry (если пакет приватный)
```bash
docker login git.mpakosrv.ru -u mpakobecex -p <ТОКЕН с read:package>
```
Если пакет сделать публичным — логин не нужен.
## 4. Запуск
```bash
# тестовый контур
docker compose -p test --env-file env/test.env -f docker-compose.prod.yml up -d
# прод (когда понадобится)
cp env/prod.env.example env/prod.env
docker compose -p prod --env-file env/prod.env -f docker-compose.prod.yml up -d
```
Логи:
```bash
docker compose -p test --env-file env/test.env -f docker-compose.prod.yml logs -f
```
## Что происходит при старте
1. `postgres` поднимается и проходит healthcheck;
2. `migrate` (**Flyway**) накатывает миграции из `sql/` — для пустой БД с нуля;
3. `clickhouse` поднимается и применяет `clickhouse/init/001_events.sql` —
**только при первой инициализации** пустого data-каталога;
4. `bot` стартует (`Запуск DispelEvilBot v<версия> (APP_ENV=...)`), аналитика и рассылки — в нём же.
Проверка контура (сервисы, миграции, Postgres, ClickHouse):
```bash
make check E=test
```
## ClickHouse (аналитика событий)
События всех действий бота пишутся в `analytics.events` (контракт — [`docs/events.md`](docs/events.md)).
ClickHouse наружу **не публикуется**: только loopback хоста (`127.0.0.1:${CLICKHOUSE_HTTP_PORT}`).
```bash
make ch E=test # clickhouse-client контура
# пример: события за сегодня по типам
docker compose -p test --env-file env/test.env -f docker-compose.prod.yml exec -T clickhouse \
sh -lc 'clickhouse-client --user "$CLICKHOUSE_USER" --password "$CLICKHOUSE_PASSWORD" \
--query "SELECT event_type, count() FROM analytics.events WHERE toDate(event_time) = today() GROUP BY event_type"'
```
Если ClickHouse недоступен, бот продолжает работать: события уходят в stdout (WARNING),
полностью выключить можно флагом `CLICKHOUSE_ENABLED=false`.
Изменения схемы: `clickhouse/init/*.sql` применяются лишь на пустом data-каталоге,
поэтому на существующем контуре DDL нужно применить вручную (`make ch E=...`).
## Бэкап событий на домашний сервер
Сырые события живут на VPS ограниченное время: раз в сутки вчерашняя партиция
выгружается в `Parquet.gz`, передаётся на домашний сервер, импортируется в тамошний
ClickHouse и сверяется по количеству строк — **только после сверки** партиции старше
`BACKUP_GRACE_DAYS` (по умолчанию 7) удаляются на VPS. На VPS остаются агрегаты
(`events_daily`, `money_daily`).
Разовая настройка:
```bash
cp env/backup.env.example env/backup.env # BACKUP_REMOTE, BACKUP_DIR, BACKUP_SSH_KEY, ...
# на домашнем сервере (в каталоге, куда кладутся архивы) разместить:
# scripts/clickhouse_import.sh
# clickhouse/init/001_events.sql -> как 001_events.sql рядом со скриптом
```
Проверочный прогон (без cron): `make backup E=test`.
Cron на VPS (вчерашний день уже закрыт, время московское):
```cron
0 4 * * * cd /opt/DispelEvilBot && ./scripts/clickhouse_backup.sh test >> /var/log/clickhouse-backup-test.log 2>&1
```
Ошибка на любом шаге оставляет данные на VPS (партиции не удаляются) и пишет понятный лог.
Импорт дня идемпотентен: повторный прогон не дублирует строки.
## Обновление и откат
```bash
# обновление: поменять IMAGE_TAG в env/<контур>.env, затем
docker compose -p <контур> --env-file env/<контур>.env -f docker-compose.prod.yml pull
docker compose -p <контур> --env-file env/<контур>.env -f docker-compose.prod.yml up -d
```
Откат — вернуть предыдущий `IMAGE_TAG` (например, commit-sha) и повторить.
## Контуры
| Контур | env-файл | БД | APP_ENV | Бот |
| --- | --- | --- | --- | --- |
| test | `env/test.env` | `dispel_evil_test` | `dev` | тестовый |
| prod | `env/prod.env` | `dispel_evil` | `prod` | боевой |
## Переменные окружения
См. `env/prod.env.example` / `env/test.env.example` (контуры) и `env/backup.env.example` (бэкап событий).
## Дашборд (позже)
Superset поднимается на домашнем сервере и читает **локальный** ClickHouse с полной
историей событий (сюда ежедневно приезжают архивы). Отдельный read-only пользователь
ClickHouse и сам дашборд — финальный этап, в этот контур не входят.
## Перенос данных на прод (позже, короткое окно простоя)
1. Остановить старого бота.
2. `pg_dump -Fc -f dump.pgc <старая_бд>`.
3. Поднять прод-контур (миграции создадут чистую схему).
4. Загрузить данные: `pg_restore --data-only --disable-triggers -d dispel_evil dump.pgc`.
5. Сверить: число пользователей, `SUM(money.amount)`, число сообщений.
6. Переключить бота, проверить команды.
Бэкап старой БД обязателен. Дубли в `tg_users`/`de_users`/`unsubscribe` при загрузке
нужно устранить до создания PK (миграция `V12` делает дедуп, но при загрузке поверх
миграций дедуп — вручную).