feat(ops): у волта Obsidian появился автоматический бэкап #3090
4 changed files with 325 additions and 0 deletions
|
|
@ -53,6 +53,12 @@ on:
|
|||
# Ровно то, что исполняется НА ОСТАЮЩЕМСЯ хосте. Намеренно НЕ включены
|
||||
# backend/** и frontend/** — их образы туда не едут.
|
||||
- "ops/*.sh"
|
||||
# ops/*.cron — эталоны crontab. Деплой их не исполняет, но после
|
||||
# разъезда хостов (#3057) правка crontab-beget.cron иначе доезжала бы
|
||||
# только до продового хоста: строка ops/*.cron есть лишь в deploy.yml.
|
||||
# Одиночная звёздочка не пересекает `/`, поэтому это именно файлы в
|
||||
# корне ops/, как и ops/*.sh рядом.
|
||||
- "ops/*.cron"
|
||||
- "Caddyfile"
|
||||
- "caddy/**"
|
||||
- "docker-compose.prod.yml"
|
||||
|
|
|
|||
249
ops/backup-couchdb.sh
Normal file
249
ops/backup-couchdb.sh
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
#!/usr/bin/env bash
|
||||
# Backup CouchDB (волт Obsidian, LiveSync) в S3.
|
||||
#
|
||||
# ЗАЧЕМ. До этого скрипта у волта не было автоматического бэкапа ВООБЩЕ:
|
||||
# ops/backup.sh закрывает Site Finder, backup-tradein-db.sh — МЕРУ,
|
||||
# backup-forgejo.sh — Forgejo, а CouchDB не закрывал никто. При этом в волте
|
||||
# лежит вся накопленная база знаний проекта — решения, разборы инцидентов,
|
||||
# ограничения, — и восстановить её из кода нельзя. Единственной копией был
|
||||
# ручной месячный прогон на машине владельца.
|
||||
#
|
||||
# ПОЧЕМУ КОНТЕЙНЕР ОСТАНАВЛИВАЕТСЯ. Файлы CouchDB пишутся append-only, но
|
||||
# снимок работающего узла может застать запись между обновлением данных и
|
||||
# обновлением заголовка базы, а .shards/ и _dbs.couch — рассогласованными между
|
||||
# собой. Документация CouchDB прямо говорит: file-level копия делается на
|
||||
# остановленном узле. Поэтому здесь stop -> tar -> start, а не tar на живом.
|
||||
# Простой — секунды (данных ~85 МБ), окно ночное, и LiveSync к обрывам связи
|
||||
# устойчив по своей природе: клиенты досинхронизируются сами.
|
||||
#
|
||||
# ГАРАНТИЯ ПОДЪЁМА. Остановленный и не поднятый обратно CouchDB — отказ хуже
|
||||
# отсутствия бэкапа, поэтому старт висит на trap EXIT: он отработает при любом
|
||||
# выходе, включая ошибку tar, нехватку места и прерывание с клавиатуры.
|
||||
# Отдельно проверяется, что контейнер после старта действительно отвечает;
|
||||
# если нет — notify().
|
||||
#
|
||||
# S3 ОБЯЗАТЕЛЕН. Как в backup-forgejo.sh и (после #3085) в backup.sh: без ключей
|
||||
# скрипт падает, а не делает молча локальную копию. Смысл бэкапа — копия ВНЕ
|
||||
# машины; локальная копия рядом с оригиналом не переживает потерю хоста.
|
||||
#
|
||||
# ЧТО КЛАДЁТСЯ. Два тома целиком: данные (базы, шарды, индексы) и конфиг
|
||||
# (local.d — админ, порты, CORS). Конфиг без данных бесполезен, данные без
|
||||
# конфига поднимаются, но требуют повторного bootstrap — держим оба.
|
||||
#
|
||||
# ВОССТАНОВЛЕНИЕ. Том обязан быть ПУСТ перед распаковкой: если развернуть
|
||||
# снимок поверх живого каталога, останутся файлы, которых в снимке уже нет, и
|
||||
# CouchDB не соберёт шарды. Порядок — остановить контейнер, очистить том,
|
||||
# распаковать в него архив, повторить для тома конфига, поднять контейнер.
|
||||
# Проверять восстановимость надо на ОТДЕЛЬНОМ томе, а не на боевом.
|
||||
#
|
||||
# Конфиг: /etc/default/gendesign-backup-couchdb
|
||||
# (см. ops/gendesign-backup-couchdb.default.example)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=./lib-backup.sh
|
||||
source "$SCRIPT_DIR/lib-backup.sh"
|
||||
|
||||
# --- config (env-overridable) ---
|
||||
COUCHDB_CONTAINER="${COUCHDB_CONTAINER:-gendesign-couchdb}"
|
||||
COUCHDB_DATA_VOLUME="${COUCHDB_DATA_VOLUME:-gendesign-obsidian_couchdb_data}"
|
||||
COUCHDB_CONFIG_VOLUME="${COUCHDB_CONFIG_VOLUME:-gendesign-obsidian_couchdb_config}"
|
||||
|
||||
LOCAL_BACKUP_DIR="${LOCAL_BACKUP_DIR:-/opt/gendesign/backups/couchdb}"
|
||||
KEEP="${KEEP:-7}"
|
||||
|
||||
# Порог — про ОБЪЁМ, а не про «нашлись ли файлы»: пустой tar.gz весит около
|
||||
# сотни байт, и без порога такой «успешный» бэкап неотличим от настоящего.
|
||||
MIN_DATA_BYTES="${MIN_DATA_BYTES:-1048576}" # 1 МБ: волт заведомо больше
|
||||
MIN_CONFIG_BYTES="${MIN_CONFIG_BYTES:-256}"
|
||||
|
||||
SENTINEL_FILE="${SENTINEL_FILE:-${LOCAL_BACKUP_DIR}/.last_success}"
|
||||
START_TIMEOUT="${START_TIMEOUT:-60}"
|
||||
|
||||
COUCHDB_BACKUP_ENV_FILE="${COUCHDB_BACKUP_ENV_FILE:-/etc/default/gendesign-backup-couchdb}"
|
||||
# shellcheck source=/dev/null
|
||||
[[ -f "$COUCHDB_BACKUP_ENV_FILE" ]] && source "$COUCHDB_BACKUP_ENV_FILE"
|
||||
|
||||
COUCHDB_S3_ENDPOINT="${COUCHDB_S3_ENDPOINT:-}"
|
||||
COUCHDB_S3_BUCKET="${COUCHDB_S3_BUCKET:-}"
|
||||
COUCHDB_S3_PREFIX="${COUCHDB_S3_PREFIX:-couchdb/}"
|
||||
COUCHDB_S3_ACCESS_KEY="${COUCHDB_S3_ACCESS_KEY:-}"
|
||||
COUCHDB_S3_SECRET_KEY="${COUCHDB_S3_SECRET_KEY:-}"
|
||||
|
||||
# Фолбэк на конфиг основного бэкапа. Отдельный ключ для волта — правильнее
|
||||
# (узкая область, как у forgejo), но требовать его как условие запуска значит
|
||||
# оставить волт вообще без бэкапа до того дня, когда до ключа дойдут руки.
|
||||
# Поэтому: заданы COUCHDB_S3_* — берём их; не заданы — берём S3_* оттуда, где
|
||||
# они уже настроены и проверены. Префикс при этом всё равно свой (couchdb/),
|
||||
# так что чужие серии в бакете не перемешиваются.
|
||||
MAIN_BACKUP_ENV_FILE="${MAIN_BACKUP_ENV_FILE:-/etc/default/gendesign-backup}"
|
||||
if [[ -z "$COUCHDB_S3_ENDPOINT" && -z "$COUCHDB_S3_ACCESS_KEY" && -f "$MAIN_BACKUP_ENV_FILE" ]]; then
|
||||
# source В ПОДОБОЛОЧКЕ, наружу выносим ровно четыре значения.
|
||||
# Прямой `source` здесь был бы тихой диверсией: конфиг основного бэкапа
|
||||
# задаёт свои LOCAL_BACKUP_DIR, KEEP и SENTINEL_FILE, и они затёрли бы уже
|
||||
# вычисленные выше значения для волта. Архивы легли бы в чужой каталог, а
|
||||
# write_sentinel в конце обновил бы сентинел ОСНОВНОГО бэкапа — его сторож
|
||||
# свежести зеленел бы по чужому прогону, то есть пропущенный дамп базы
|
||||
# перестал бы замечаться вовсе.
|
||||
eval "$(
|
||||
# shellcheck source=/dev/null
|
||||
source "$MAIN_BACKUP_ENV_FILE" >/dev/null 2>&1 || true
|
||||
printf 'COUCHDB_S3_ENDPOINT=%q\n' "${S3_ENDPOINT:-}"
|
||||
printf 'COUCHDB_S3_BUCKET=%q\n' "${S3_BUCKET:-}"
|
||||
printf 'COUCHDB_S3_ACCESS_KEY=%q\n' "${S3_ACCESS_KEY:-}"
|
||||
printf 'COUCHDB_S3_SECRET_KEY=%q\n' "${S3_SECRET_KEY:-}"
|
||||
)"
|
||||
[[ -n "$COUCHDB_S3_ACCESS_KEY" ]] && \
|
||||
log "S3: отдельный ключ для волта не задан — беру настройки из ${MAIN_BACKUP_ENV_FILE}, префикс ${COUCHDB_S3_PREFIX}"
|
||||
fi
|
||||
|
||||
# --- guard 0: S3 обязателен, и проверяется ДО всякой остановки контейнера ---
|
||||
# Порядок важен: незачем ронять волт ради бэкапа, которому некуда уехать.
|
||||
if [[ -z "$COUCHDB_S3_ENDPOINT" || -z "$COUCHDB_S3_BUCKET" || -z "$COUCHDB_S3_ACCESS_KEY" || -z "$COUCHDB_S3_SECRET_KEY" ]]; then
|
||||
log "ERROR: бэкап CouchDB НЕ НАСТРОЕН." >&2
|
||||
log "ERROR: не заданы COUCHDB_S3_ENDPOINT / COUCHDB_S3_BUCKET / COUCHDB_S3_ACCESS_KEY / COUCHDB_S3_SECRET_KEY." >&2
|
||||
log "ERROR: заполни ${COUCHDB_BACKUP_ENV_FILE} (образец — ops/gendesign-backup-couchdb.default.example)" >&2
|
||||
log "ERROR: либо настрой S3_* в ${MAIN_BACKUP_ENV_FILE:-/etc/default/gendesign-backup} — оттуда берётся фолбэк." >&2
|
||||
log "ERROR: локальная копия рядом с оригиналом смысла не имеет — не делаю её и контейнер не трогаю." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- guard 1: контейнер и оба тома существуют ---
|
||||
if ! docker inspect "$COUCHDB_CONTAINER" >/dev/null 2>&1; then
|
||||
log "ERROR: контейнер ${COUCHDB_CONTAINER} не найден — переопредели COUCHDB_CONTAINER." >&2
|
||||
exit 1
|
||||
fi
|
||||
for v in "$COUCHDB_DATA_VOLUME" "$COUCHDB_CONFIG_VOLUME"; do
|
||||
if ! docker volume inspect "$v" >/dev/null 2>&1; then
|
||||
log "ERROR: том ${v} не найден — переопредели COUCHDB_DATA_VOLUME / COUCHDB_CONFIG_VOLUME." >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p "$LOCAL_BACKUP_DIR"
|
||||
TS="$(date -u +%Y%m%d_%H%M%S)"
|
||||
data_out="${LOCAL_BACKUP_DIR}/couchdb-data_${TS}.tar.gz"
|
||||
config_out="${LOCAL_BACKUP_DIR}/couchdb-config_${TS}.tar.gz"
|
||||
|
||||
# --- гарантия подъёма: старт висит на EXIT, а не на успешном пути ---
|
||||
COUCHDB_WAS_STOPPED=0
|
||||
restart_couchdb() {
|
||||
local rc=$?
|
||||
if [[ "$COUCHDB_WAS_STOPPED" == "1" ]]; then
|
||||
log "Поднимаю ${COUCHDB_CONTAINER} обратно."
|
||||
if ! docker start "$COUCHDB_CONTAINER" >/dev/null 2>&1; then
|
||||
log "CRITICAL: не удалось запустить ${COUCHDB_CONTAINER} — волт лежит." >&2
|
||||
notify "CouchDB backup: контейнер ${COUCHDB_CONTAINER} ОСТАНОВЛЕН и не поднялся. Волт недоступен, нужно вмешательство."
|
||||
return "$rc"
|
||||
fi
|
||||
local up=0
|
||||
for _ in $(seq 1 "$START_TIMEOUT"); do
|
||||
if docker exec "$COUCHDB_CONTAINER" curl -fsS http://localhost:5984/_up >/dev/null 2>&1; then
|
||||
up=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [[ "$up" == "1" ]]; then
|
||||
log "CouchDB отвечает."
|
||||
else
|
||||
log "CRITICAL: ${COUCHDB_CONTAINER} запущен, но /_up молчит ${START_TIMEOUT}с." >&2
|
||||
notify "CouchDB backup: контейнер поднят, но /_up не отвечает ${START_TIMEOUT}с. Проверь волт."
|
||||
fi
|
||||
fi
|
||||
return "$rc"
|
||||
}
|
||||
trap restart_couchdb EXIT
|
||||
|
||||
log "Останавливаю ${COUCHDB_CONTAINER} для снятия консистентного снимка."
|
||||
docker stop "$COUCHDB_CONTAINER" >/dev/null
|
||||
COUCHDB_WAS_STOPPED=1
|
||||
|
||||
# tar идёт в одноразовом контейнере: том примонтирован read-only, писать он
|
||||
# может только в каталог бэкапов.
|
||||
#
|
||||
# Про владельца. Читать файлы тома надо от root (внутри они принадлежат uid
|
||||
# CouchDB), поэтому контейнер запускается от root — и архив наружу выходит
|
||||
# root:root, в отличие от остальных серий в этом каталоге. Само по себе это
|
||||
# ротацию не ломает (удаление зависит от прав КАТАЛОГА, а он наш), но ставит
|
||||
# каталог в зависимость от того, что никто не включит на нём sticky-бит, и
|
||||
# ломает ручную работу с файлами из-под непривилегированного пользователя.
|
||||
# Поэтому chown делаем тут же, внутри контейнера, где root ещё есть.
|
||||
HOST_UID="$(id -u)"
|
||||
HOST_GID="$(id -g)"
|
||||
tar_volume() {
|
||||
local volume="$1" out="$2" name
|
||||
name="$(basename "$out")"
|
||||
docker run --rm \
|
||||
-v "${volume}":/src:ro \
|
||||
-v "${LOCAL_BACKUP_DIR}":/out \
|
||||
alpine:3 \
|
||||
sh -c "tar czf /out/${name} -C /src . && chown ${HOST_UID}:${HOST_GID} /out/${name}"
|
||||
}
|
||||
|
||||
log "Снимок данных: ${COUCHDB_DATA_VOLUME}"
|
||||
tar_volume "$COUCHDB_DATA_VOLUME" "$data_out"
|
||||
log "Снимок конфига: ${COUCHDB_CONFIG_VOLUME}"
|
||||
tar_volume "$COUCHDB_CONFIG_VOLUME" "$config_out"
|
||||
|
||||
# Контейнер поднимается СРАЗУ после копирования, до проверок и выгрузки:
|
||||
# держать волт лежачим на время верификации архивов и заливки в S3 незачем.
|
||||
log "Поднимаю ${COUCHDB_CONTAINER} — копирование закончено."
|
||||
docker start "$COUCHDB_CONTAINER" >/dev/null
|
||||
COUCHDB_WAS_STOPPED=0
|
||||
for _ in $(seq 1 "$START_TIMEOUT"); do
|
||||
docker exec "$COUCHDB_CONTAINER" curl -fsS http://localhost:5984/_up >/dev/null 2>&1 && break
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# --- проверки целостности ---
|
||||
check_archive() {
|
||||
local f="$1" floor="$2" what="$3"
|
||||
local bytes
|
||||
bytes=$(stat -c %s "$f" 2>/dev/null || echo 0)
|
||||
if (( bytes < floor )); then
|
||||
log "ERROR: ${what} — всего ${bytes} байт (< ${floor}), снимок пустой или битый." >&2
|
||||
notify "CouchDB backup: ${what} — ${bytes} байт, ниже порога ${floor}. Бэкап НЕ засчитан."
|
||||
exit 1
|
||||
fi
|
||||
if ! tar -tzf "$f" >/dev/null 2>&1; then
|
||||
log "ERROR: ${what} не читается как tar.gz." >&2
|
||||
notify "CouchDB backup: архив ${what} повреждён, tar -tzf не прошёл. Бэкап НЕ засчитан."
|
||||
exit 1
|
||||
fi
|
||||
log "${what} OK: $(basename "$f") (${bytes} байт, файлов: $(tar -tzf "$f" | wc -l))"
|
||||
}
|
||||
check_archive "$data_out" "$MIN_DATA_BYTES" "снимок данных"
|
||||
check_archive "$config_out" "$MIN_CONFIG_BYTES" "снимок конфига"
|
||||
|
||||
# --- выгрузка в S3 (обязательна — см. guard 0) ---
|
||||
for f in "$data_out" "$config_out"; do
|
||||
key="${COUCHDB_S3_PREFIX%/}/$(basename "$f")"
|
||||
log "Выгружаю в s3://${COUCHDB_S3_BUCKET}/${key}"
|
||||
# AWS_CA_BUNDLE — та же поправка, что в backup.sh и backup-forgejo.sh:
|
||||
# у aws-cli v2 свой вшитый набор корней, и корня Selectel в нём нет.
|
||||
docker run --rm \
|
||||
-e AWS_ACCESS_KEY_ID="$COUCHDB_S3_ACCESS_KEY" \
|
||||
-e AWS_SECRET_ACCESS_KEY="$COUCHDB_S3_SECRET_KEY" \
|
||||
-e AWS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
|
||||
-v "$LOCAL_BACKUP_DIR":/backup:ro \
|
||||
amazon/aws-cli:latest \
|
||||
--endpoint-url "$COUCHDB_S3_ENDPOINT" \
|
||||
s3 cp --no-progress "/backup/$(basename "$f")" "s3://${COUCHDB_S3_BUCKET}/${key}"
|
||||
done
|
||||
log "Выгрузка в S3 прошла."
|
||||
|
||||
# --- локальная ротация ---
|
||||
for pattern in "couchdb-data_" "couchdb-config_"; do
|
||||
# shellcheck disable=SC2012
|
||||
ls -1t "${LOCAL_BACKUP_DIR}/${pattern}"*.tar.gz 2>/dev/null \
|
||||
| tail -n +"$((KEEP + 1))" \
|
||||
| xargs -r rm -f
|
||||
done
|
||||
|
||||
log "Бэкап CouchDB готов. Локальных копий оставлено: до ${KEEP} на каждый том."
|
||||
|
||||
# Сентинел пишется ТОЛЬКО после выгрузки: сторож свежести обязан зеленеть по
|
||||
# факту копии вне машины, а не по факту того, что скрипт дошёл до конца.
|
||||
write_sentinel "$SENTINEL_FILE"
|
||||
|
|
@ -24,6 +24,21 @@
|
|||
# Сторож пропущенных прогонов для forgejo-бэкапа. Порог 26ч.
|
||||
0 * * * * bash /opt/gendesign/ops/check-backup-staleness.sh /opt/gendesign/backups/forgejo/.last_success 26 "forgejo backup" >> /opt/gendesign/logs/backup-staleness.log 2>&1
|
||||
|
||||
# ── Бэкап волта Obsidian (CouchDB) ──────────────────────────────────────────
|
||||
# Волт остаётся на этом хосте вместе с Forgejo и GlitchTip, поэтому запись
|
||||
# живёт здесь, а не в crontab-poincare. До #3057 у CouchDB не было
|
||||
# автоматического бэкапа вообще — единственной копией был ручной месячный
|
||||
# прогон на машине владельца.
|
||||
# Скрипт ОСТАНАВЛИВАЕТ CouchDB на время снятия снимка (секунды, данных ~85 МБ):
|
||||
# file-level копия работающего узла может оказаться рассогласованной. Время —
|
||||
# 04:45, между forgejo-бэкапом (04:15) и недельной уборкой докера (04:00 вс),
|
||||
# чтобы три задачи не дрались за диск и сеть одновременно.
|
||||
45 4 * * * bash /opt/gendesign/ops/backup-couchdb.sh >> /opt/gendesign/logs/backup-couchdb.log 2>&1
|
||||
|
||||
# Сторож пропущенных прогонов для бэкапа волта. Порог 26ч — как у остальных:
|
||||
# сутки плюс запас на сдвиг прогона.
|
||||
0 * * * * bash /opt/gendesign/ops/check-backup-staleness.sh /opt/gendesign/backups/couchdb/.last_success 26 "couchdb backup" >> /opt/gendesign/logs/backup-staleness.log 2>&1
|
||||
|
||||
# ── Уборка докера ───────────────────────────────────────────────────────────
|
||||
# Остаётся здесь, потому что здесь остаются CI-раннеры (#2881) — именно их
|
||||
# тома и растут. На Selectel нужна СВОЯ такая же запись (см. crontab-poincare).
|
||||
|
|
|
|||
55
ops/gendesign-backup-couchdb.default.example
Normal file
55
ops/gendesign-backup-couchdb.default.example
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Образец /etc/default/gendesign-backup-couchdb
|
||||
#
|
||||
# Читается ops/backup-couchdb.sh. Файл содержит ключ S3 — держать 0600 и
|
||||
# владельцем того пользователя, под которым стоит крон-задача.
|
||||
#
|
||||
# Установка:
|
||||
# sudo install -m 0600 -o gendesign -g gendesign \
|
||||
# ops/gendesign-backup-couchdb.default.example /etc/default/gendesign-backup-couchdb
|
||||
# sudo -e /etc/default/gendesign-backup-couchdb # подставить реальные ключи
|
||||
#
|
||||
# ЭТОТ ФАЙЛ НЕОБЯЗАТЕЛЕН. Если COUCHDB_S3_ENDPOINT и COUCHDB_S3_ACCESS_KEY не
|
||||
# заданы, скрипт берёт S3_* из /etc/default/gendesign-backup — того же ключа,
|
||||
# которым уже выгружается основной бэкап, но под своим префиксом couchdb/.
|
||||
# Заводить файл стоит, когда для волта появится ОТДЕЛЬНЫЙ узкий ключ (как у
|
||||
# forgejo): своя область доступа лучше общей, просто не ценой отсутствия
|
||||
# бэкапа вовсе.
|
||||
#
|
||||
# Если не настроено ни здесь, ни там — скрипт откажется работать и НЕ станет
|
||||
# останавливать CouchDB: бэкап без выгрузки за пределы машины смысла не имеет.
|
||||
|
||||
# --- S3 (либо здесь, либо фолбэк на /etc/default/gendesign-backup) ----------
|
||||
COUCHDB_S3_ENDPOINT=https://s3.ru-1.storage.selcloud.ru
|
||||
COUCHDB_S3_BUCKET=gendsgn-backups
|
||||
COUCHDB_S3_PREFIX=couchdb/
|
||||
COUCHDB_S3_ACCESS_KEY=
|
||||
COUCHDB_S3_SECRET_KEY=
|
||||
|
||||
# --- что копируем (значения по умолчанию совпадают с боевыми) ---------------
|
||||
# Имена берутся из docker-compose.obsidian.yml, проект gendesign-obsidian.
|
||||
#COUCHDB_CONTAINER=gendesign-couchdb
|
||||
#COUCHDB_DATA_VOLUME=gendesign-obsidian_couchdb_data
|
||||
#COUCHDB_CONFIG_VOLUME=gendesign-obsidian_couchdb_config
|
||||
|
||||
# --- локальное хранение -----------------------------------------------------
|
||||
#LOCAL_BACKUP_DIR=/opt/gendesign/backups/couchdb
|
||||
#KEEP=7
|
||||
|
||||
# --- пороги целостности -----------------------------------------------------
|
||||
# Про объём, а не про наличие файла: пустой архив весит около сотни байт и без
|
||||
# порога неотличим от настоящего бэкапа. Поднимать, если волт заметно вырос.
|
||||
#MIN_DATA_BYTES=1048576
|
||||
#MIN_CONFIG_BYTES=256
|
||||
|
||||
# Сколько секунд ждать ответа /_up после подъёма контейнера.
|
||||
#START_TIMEOUT=60
|
||||
|
||||
# --- оповещения -------------------------------------------------------------
|
||||
# Дублировать сюда ничего не надо: notify() из ops/lib-backup.sh, не найдя
|
||||
# TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID в окружении, сам читает
|
||||
# /etc/default/gendesign-backup. То есть канал общий с остальными бэкапами.
|
||||
# Переопределяй только если этому бэкапу нужен ОТДЕЛЬНЫЙ адресат:
|
||||
#TELEGRAM_BOT_TOKEN=
|
||||
#TELEGRAM_CHAT_ID=
|
||||
# Либо укажи другой файл, откуда notify() возьмёт настройки канала:
|
||||
#BACKUP_ENV_FILE=/etc/default/gendesign-backup
|
||||
Loading…
Add table
Reference in a new issue