# crontab ПРИНИМАЮЩЕГО хоста (Selectel Poincare, 188.124.37.140) — после 30.08. # # Устанавливать СРАЗУ после того, как стек поднялся и смоук прошёл: # mkdir -p /opt/gendesign/logs # crontab /opt/gendesign/ops/crontab-poincare.cron # crontab -l # сверить # # Перед установкой в /etc/default/ должны лежать (root-owned, chmod 600, # НЕ в git, переносятся руками с предыдущего хоста или создаются заново): # /etc/default/gendesign-backup — S3_ENDPOINT/S3_BUCKET/S3_ACCESS_KEY/S3_SECRET_KEY # (см. ops/gendesign-backup.default.example) # /etc/default/tradein-backup — свои S3_*, либо отсутствует (тогда # backup-tradein-db.sh падает на общий # /etc/default/gendesign-backup выше) # Без них ops/backup.sh и backup-tradein-db.sh теперь падают громко (#3085), # а не молча пишут локальный бэкап. # # ⚠️ САМЫЙ ОПАСНЫЙ ПРОПУСК ВСЕГО ПЕРЕЕЗДА. Если этот файл не установить, # на новом хосте НЕ БУДЕТ НИ ОДНОГО БЭКАПА — ни tradein, ни gendesign. И узнать # об этом будет неоткуда: сторож пропущенных прогонов (check-backup-staleness) # сам живёт в этом же crontab'е, то есть его тоже не будет. Отсутствие бэкапов # обнаружится в момент, когда они понадобятся. # # Времена оставлены те же, что были на Beget — чтобы не гадать, изменилось ли # поведение из-за переезда или из-за нового расписания. Подгонять окна имеет # смысл ПОСЛЕ того, как всё поедет стабильно. # ── Бэкапы обоих кластеров ────────────────────────────────────────────────── # Off-box выгрузка в S3 включается через /etc/default/tradein-backup и # /etc/default/gendesign-backup — файлы НЕ переезжают сами (в git их нет и не # должно быть), их нужно перенести руками. Без них оба скрипта падают ГРОМКО # (exit 1, дамп не снимается вовсе) — см. #3085; они больше НЕ пишут молча # локальный бэкап. 30 3 * * * bash /opt/gendesign/ops/backup.sh >> /opt/gendesign/logs/gendesign-backup.log 2>&1 30 4 * * * bash /opt/gendesign/tradein-mvp/deploy/backup-tradein-db.sh >> /opt/gendesign/logs/tradein-backup.log 2>&1 # Сторожа пропущенных прогонов, порог 26ч. Едут вместе со своими бэкапами: # сторож должен жить там же, где sentinel, иначе он сторожит файл, который # никто не обновляет, и кричит вечно. 0 * * * * bash /opt/gendesign/ops/check-backup-staleness.sh /opt/gendesign/backups/.last_success 26 "gendesign main backup" >> /opt/gendesign/logs/backup-staleness.log 2>&1 0 * * * * bash /opt/gendesign/ops/check-backup-staleness.sh /opt/gendesign/backups/tradein/.last_success 26 "tradein backup" >> /opt/gendesign/logs/backup-staleness.log 2>&1 # ── Restore-дрель, раз в месяц (#3085) ─────────────────────────────────────── # Восстановимость дампа никогда не проверялась автоматически — только # ручными прогонами. 1-е число месяца, 02:15 — до ночных бэкапов (03:30/04:30) # и до обогащения/геокодинга (05:00-05:45), не пересекается ни с чем. # Берёт САМЫЙ СВЕЖИЙ на тот момент main-дамп; ops/restore-drill.sh сам найдёт # рядом лежащий globals-файл и сам снесёт свой временный контейнер — прод не # трогает никогда (см. заголовок скрипта). 15 2 1 * * bash -c 'f=$(ls -t /opt/gendesign/backups/gendesign_[0-9]*.sql.gz 2>/dev/null | head -1); if [ -n "$f" ]; then bash /opt/gendesign/ops/restore-drill.sh "$f"; else echo "no gendesign dump found to drill"; exit 1; fi' >> /opt/gendesign/logs/restore-drill.log 2>&1 # Та же дрель для базы tradein — она НЕ покрывалась строкой выше (#2203). # Строка выше берёт только `gendesign_*`, то есть восстановимость базы # клиентских оценок автоматически не проверялась вовсе: ни листинги, ни дома, # ни сами оценки. Замер 27.08: дамп 343 МБ разворачивается за 58 c и сходится # с боевой базой построчно (houses 10400, listings 109978, deals 108623 — # расхождения только по строкам, созданным ПОСЛЕ снятия дампа). # # Еженедельно, а не раз в месяц: две минуты работы против месяца, в течение # которого битый дамп остаётся незамеченным. Понедельник 03:00 — после # монтажной дрели gendesign (02:15 первого числа, ей хватает форы даже когда # первое выпадает на понедельник) и до ночных бэкапов в 03:30. 0 3 * * 1 bash -c 'f=$(ls -t /opt/gendesign/backups/tradein/tradein-[0-9]*.sql.gz 2>/dev/null | head -1); if [ -n "$f" ]; then bash /opt/gendesign/ops/restore-drill.sh "$f"; else echo "no tradein dump found to drill"; exit 1; fi' >> /opt/gendesign/logs/restore-drill.log 2>&1 # ── Off-box копия рантайм-конфига (#2203) ──────────────────────────────────── # Четвёртый пункт приёмки #2203. В дампах есть колонки под pgp_sym_encrypt; # ключ к ним лежит на самой машине и никуда не уезжает. Потеря машины = # дампы есть, расшифровать нечем. # # 04:10 — после обоих ночных бэкапов (03:30 и 04:30 идёт tradein, но он берёт # свой дамп независимо), до обогащения в 05:00. Ежедневно, потому что копия # должна соответствовать дампу того же дня: конфиг меняют редко, но если # поменяли, старая копия не расшифрует свежий дамп. # # Скрипт fail-closed: без ENV_OFFBOX_PASSPHRASE в /etc/default/gendesign-backup # он НЕ выгружает файл открытым, а падает с явным сообщением и алертом. # Открытым в тот же бакет, где лежат дампы, класть нельзя — это обнулило бы # шифрование колонок (ключ рядом с шифротекстом). 10 4 * * * bash /opt/gendesign/ops/backup-env-offbox.sh >> /opt/gendesign/logs/env-offbox.log 2>&1 # ── Обогащение и геокодирование (ходят в tradein-backend) ─────────────────── 0 5 * * * cd /opt/gendesign/tradein-mvp && docker exec tradein-backend python -m scripts.backfill_houses_dadata --limit 100 --priority both >> /opt/gendesign/logs/dadata-backfill.log 2>&1 30 5 * * * cd /opt/gendesign/tradein-mvp && docker exec tradein-backend python -m scripts.geocode_deals_from_houses --limit 50000 >> /opt/gendesign/logs/deals-geocode.log 2>&1 45 5 * * * cd /opt/gendesign/tradein-mvp && docker exec tradein-backend python -m scripts.geocode_deals_nominatim --limit 5000 >> /opt/gendesign/logs/deals-nominatim.log 2>&1 # ── Уборка докера ─────────────────────────────────────────────────────────── # СВОЯ запись, не «переехавшая»: на Beget она чистит тома CI-раннеров, здесь — # образы продуктового стека. Нужны обе, на обоих хостах. 0 4 * * 0 bash /opt/gendesign/ops/docker-prune.sh >> /opt/gendesign/logs/docker-prune.log 2>&1 # ── Логи: /opt/gendesign/logs, а не /tmp ──────────────────────────────────── # На Beget половина записей писала в /tmp — он чистится при перезагрузке, и # именно поэтому историю отказов бэкапов там восстановить не удавалось. # Каталог создать до установки crontab: mkdir -p /opt/gendesign/logs # # ── ЧЕГО ЗДЕСЬ НЕТ ────────────────────────────────────────────────────────── # backup-forgejo.sh + его сторож — Forgejo остаётся на Beget # (см. ops/crontab-beget.cron)