DispelEvilBot/DEPLOY.md

7.3 KiB
Raw Permalink Blame History

Развёртывание

Клонируем репозиторий и поднимаем контур Compose-ом. Контуры test и prod разделяются именем проекта (-p) и файлом окружения (--env-file) — у каждого свои БД и volume'ы, на одной машине не пересекаются.

1. Клонировать

git clone ssh://git@<gitea-host>:2222/mpakobecex/DispelEvilBot.git
cd DispelEvilBot

2. Подготовить окружение

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 (если пакет приватный)

docker login git.mpakosrv.ru -u mpakobecex -p <ТОКЕН с read:package>

Если пакет сделать публичным — логин не нужен.

4. Запуск

# тестовый контур
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

Логи:

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):

make check E=test

ClickHouse (аналитика событий)

События всех действий бота пишутся в analytics.events (контракт — docs/events.md). ClickHouse наружу не публикуется: только loopback хоста (127.0.0.1:${CLICKHOUSE_HTTP_PORT}).

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).

Разовая настройка:

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 (вчерашний день уже закрыт, время московское):

0 4 * * * cd /opt/DispelEvilBot && ./scripts/clickhouse_backup.sh test >> /var/log/clickhouse-backup-test.log 2>&1

Ошибка на любом шаге оставляет данные на VPS (партиции не удаляются) и пишет понятный лог. Импорт дня идемпотентен: повторный прогон не дублирует строки.

Обновление и откат

# обновление: поменять 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 делает дедуп, но при загрузке поверх миграций дедуп — вручную).