9.4 KiB
Развёртывание
Клонируем репозиторий и поднимаем контур 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).
Порт админки (ADMIN_HTTP_PORT) — так же: prod — 8000, test — 8001.
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
Что происходит при старте
postgresподнимается и проходит healthcheck;migrate(Flyway) накатывает миграции изsql/— для пустой БД с нуля;clickhouseподнимается и применяетclickhouse/init/001_events.sql— только при первой инициализации пустого data-каталога;botстартует (Запуск DispelEvilBot v<версия> (APP_ENV=...)), аналитика и рассылки — в нём же;adminстартует и отвечает наGET /healthz(порт на loopback хоста).
Проверка контура (сервисы, миграции, 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=...).
Админка (FastAPI)
Сервис admin — отдельный образ mpakobecex/dispelevilbot-admin, общий пакет common.
Наружу пока не публикуется: только loopback хоста (127.0.0.1:${ADMIN_HTTP_PORT}).
Домен и TLS появятся вместе с входом через Telegram (Блоки 2.4/4.2).
# проверка живости
curl -s http://127.0.0.1:8001/healthz # test
curl -s http://127.0.0.1:8000/healthz # prod
Локально без Docker: pip install -r requirements-admin.txt && python -m admin
(по умолчанию 0.0.0.0:8000, переопределяется ADMIN_HOST/ADMIN_PORT).
Бэкап событий (забирает домашний сервер)
Сырые события живут на VPS ограниченное время: раз в сутки домашний сервер сам забирает
вчерашнюю партицию (pull), складывает её в Parquet.gz, импортирует в свой ClickHouse и
сверяет количество строк — только после сверки на VPS удаляются партиции старше
BACKUP_GRACE_DAYS (по умолчанию 7). На VPS остаются агрегаты (events_daily, money_daily).
Входящий SSH на домашний сервер не нужен: он инициирует соединение сам.
Разовая настройка:
# на домашнем сервере
git clone ssh://git@<gitea-host>:2222/mpakobecex/DispelEvilBot.git
cd DispelEvilBot
cp env/backup.env.example env/backup.env # VPS_SSH, VPS_PORT, VPS_PROJECT_DIR, VPS_SSH_KEY, BACKUP_DIR, CLICKHOUSE_*
Требования: на VPS — пользователь с доступом к docker и каталог с репозиторием
(VPS_PROJECT_DIR, там запускается docker compose); на домашнем сервере — clickhouse-client
и локальный ClickHouse. Настройка SSH-доступа — deploy/ssh-access.md.
Если ставить clickhouse-client на хост не хочется, укажите в env/backup.env переменную
CLICKHOUSE_CLIENT — путь к обёртке, которая выполняет клиент внутри контейнера:
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
exec docker compose --env-file env/backup.env -f docker-compose.yml exec -T clickhouse clickhouse-client "$@"
Проверочный прогон (без cron): make backup E=test или ./scripts/clickhouse_backup.sh test.
Cron на домашнем сервере (вчерашний день уже закрыт, время московское):
0 4 * * * cd /srv/DispelEvilBot && ./scripts/clickhouse_backup.sh test >> /var/log/clickhouse-backup-test.log 2>&1
Ошибка на любом шаге оставляет данные на VPS (партиции не удаляются) и пишет понятный лог. Импорт дня идемпотентен: повторный прогон не дублирует строки.
Если контур на VPS не запущен (нет работающего clickhouse или не найден каталог проекта),
скрипт пишет об этом в лог и завершается с кодом 0 — для cron это не ошибка.
Обновление и откат
# обновление: поменять 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 и сам дашборд — финальный этап, в этот контур не входят.
Перенос данных на прод (позже, короткое окно простоя)
- Остановить старого бота.
pg_dump -Fc -f dump.pgc <старая_бд>.- Поднять прод-контур (миграции создадут чистую схему).
- Загрузить данные:
pg_restore --data-only --disable-triggers -d dispel_evil dump.pgc. - Сверить: число пользователей,
SUM(money.amount), число сообщений. - Переключить бота, проверить команды.
Бэкап старой БД обязателен. Дубли в tg_users/de_users/unsubscribe при загрузке
нужно устранить до создания PK (миграция V12 делает дедуп, но при загрузке поверх
миграций дедуп — вручную).