Каждый run и verify шлёт в чаты BACKUP_TELEGRAM_CHAT_ID одно сообщение: успех со сводкой (игроки/партии, по репозиторию снимок, число снимков, размер) или сбой с причиной — в том числе ранний отказ (нет пароля, занят lock, битая БД): обработчик EXIT берёт текст последнего die. Недоступный Telegram бэкап не ломает. Бот-слушатель (fs-backup telegram bot, long polling, стартует из entrypoint в фоне) отвечает на /backups (хранящиеся снимки), /status и /help только чатам из белого списка; чужие chat id пишет в журнал. telegram chats — узнать свой id, telegram test — проверить связь. Токен по умолчанию — TELEGRAM_BOT_TOKEN приложения (тот же бот), BACKUP_TELEGRAM_BOT_TOKEN переопределяет. В образ добавлен curl. Настройка — deploy/backup/README.md, раздел 10. #83 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LqSoRj99iwVEH5U5fnZgsd
47 lines
2.4 KiB
Bash
47 lines
2.4 KiB
Bash
#!/bin/sh
|
|
# Точка входа контейнера backup: первый снимок (если снимков ещё нет) и расписание.
|
|
# Расписание — supercronic по BACKUP_SCHEDULE (бэкап) и BACKUP_VERIFY_SCHEDULE (проверка).
|
|
set -eu
|
|
|
|
log() { printf '[backup %s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"; }
|
|
|
|
# Telegram-бот (#83): отвечает владельцу на /backups и /status. Стартует раньше проверки
|
|
# пароля — при выключенных бэкапах скажет, что они выключены. Упал — перезапуск через минуту.
|
|
if [ -n "${BACKUP_TELEGRAM_BOT_TOKEN:-}" ] && [ -n "${BACKUP_TELEGRAM_CHAT_ID:-}" ]; then
|
|
( while :; do fs-backup telegram bot || true; sleep 60; done ) &
|
|
else
|
|
log "Telegram не настроен (BACKUP_TELEGRAM_CHAT_ID/токен бота) — отчёты в Telegram выключены."
|
|
fi
|
|
|
|
# Без пароля бэкапы невозможны. Не падаем (иначе restart-петля и спам в логах) — ждём,
|
|
# пока пароль появится в .env; healthcheck при этом показывает unhealthy.
|
|
if [ -z "${BACKUP_PASSWORD:-}" ]; then
|
|
log "BACKUP_PASSWORD не задан в .env — бэкапы ОТКЛЮЧЕНЫ."
|
|
log "Настройка по шагам: deploy/backup/README.md. После правки .env: docker compose up -d backup"
|
|
exec tail -f /dev/null
|
|
fi
|
|
|
|
mkdir -p /tmp/fs-backup
|
|
CRONTAB=/tmp/fs-backup/crontab
|
|
: > "$CRONTAB"
|
|
if [ -n "${BACKUP_SCHEDULE:-}" ]; then
|
|
echo "${BACKUP_SCHEDULE} fs-backup run --scheduled" >> "$CRONTAB"
|
|
fi
|
|
if [ -n "${BACKUP_VERIFY_SCHEDULE:-}" ]; then
|
|
echo "${BACKUP_VERIFY_SCHEDULE} fs-backup verify" >> "$CRONTAB"
|
|
fi
|
|
|
|
if [ ! -s "$CRONTAB" ]; then
|
|
log "Расписание отключено — только ручной запуск: docker compose exec backup fs-backup run"
|
|
exec tail -f /dev/null
|
|
fi
|
|
|
|
if ! fs-backup has-snapshots; then
|
|
log "Снимков в локальном репозитории ещё нет — делаю первый бэкап сразу."
|
|
fs-backup run --scheduled || log "Первый бэкап не удался — следующая попытка по расписанию."
|
|
fi
|
|
|
|
log "Расписание (TZ=${TZ:-UTC}):"
|
|
sed 's/^/[backup] /' "$CRONTAB"
|
|
exec supercronic -passthrough-logs "$CRONTAB"
|