feat(ops): бэкапить конфигурацию Forgejo, а не только его содержимое #3073

Merged
lekss361 merged 1 commit from feat/backup-forgejo-config into main 2026-08-24 03:49:58 +00:00
Owner

Продолжение #2203. Нашлось при разборе #3030 — искал, где выставить лимит памяти Forgejo, и обнаружил, что его вообще нет ни в репозитории, ни в бэкапе.

Пробел

backup-forgejo.sh забирает две вещи: дамп БД и tar голых репозиториев. То есть содержимое Forgejo — но не то, чем оно поднимается.

Компоуз-файлы Forgejo и раннеров живут в /home/gendesign/forgejo/, вне репозитория:

$ git -C /home/gendesign/forgejo rev-parse --is-inside-work-tree
fatal: not a git repository

Их не трогает ни один деплой (включая свежий #3071 — тот синхронизирует /opt/gendesign) и не покрывал ни один бэкап.

Практический смысл: при потере хоста БД и репозитории восстановятся, а конфигурация — нет. Пришлось бы вручную воссоздавать docker-compose.yml и заново регистрировать три раннера.

Для переезда это особенно неприятно: Forgejo остаётся на Beget, то есть он и есть та машина, с которой всё будет подниматься, если что-то пойдёт не так.

Косвенное подтверждение, что каталог правится руками и без истории — рядом лежат три самодельных снимка вместо version control:

runner-compose.yml.bak
runner-compose.yml.bak.1779049805
runner-compose.yml.bak.before-runner3

Что сделано

Третий артефакт forgejo-config_<ts>.tar.gz рядом с дампом и repo-бандлом, уезжает в S3 тем же циклом.

Что намеренно НЕ включено: секрет-файл режима 600 и runner*/data/ с регистрационными токенами. Они остаются ручным off-box пунктом владельца — тем же, что рантайм-секреты в приёмке #2203. Логика простая: раннеры при восстановлении перерегистрируются из UI за пару минут, а компоуз-файл руками не восстановишь.

Мягкая деградация: не собрался — WARN и продолжаем без него. Бэкап БД и репозиториев не должен теряться из-за 5 КБ конфига. Проверки те же две, что у repo-бандла — не «объём», а «собрался и читается».

Test plan

Прогнал ровно ту же команду tar против настоящего каталога на проде, read-only, боевой бэкап не тронут:

  • tar код возврата 0
  • В архиве ровно 2 файла: docker-compose.yml, runner-compose.yml
  • 1070 байт, архив читается (tar -tzf)
  • Секрет-файла внутри нет (0 совпадений), каталога data/ внутри нет (0) — то есть ни секретов, ни дублирования repo-бандла
  • Раскрытие ${config_out:+"$config_out"} в цикле выгрузки: пусто → 2 файла, задано → 3
  • bash -n чист
  • Временный тестовый архив удалён

Побочно — к #3030

Заодно выяснилось, почему пункт «лимиты выставлены» там нельзя закрыть через PR целиком: Forgejo (2.235 ГиБ, самый крупный потребитель) и три раннера описаны файлами вне git. Выставить им mem_limit можно только правкой этих файлов на хосте — это не код, это ручная работа на проде. В репозитории лимитами управляемы только docker-compose.prod.yml и docker-compose.obsidian.yml.

Refs #2203, #3057, #3030

Продолжение #2203. Нашлось при разборе #3030 — искал, где выставить лимит памяти Forgejo, и обнаружил, что его вообще нет ни в репозитории, ни в бэкапе. ## Пробел `backup-forgejo.sh` забирает две вещи: дамп БД и tar голых репозиториев. То есть **содержимое** Forgejo — но не то, **чем** оно поднимается. Компоуз-файлы Forgejo и раннеров живут в `/home/gendesign/forgejo/`, **вне репозитория**: ``` $ git -C /home/gendesign/forgejo rev-parse --is-inside-work-tree fatal: not a git repository ``` Их не трогает ни один деплой (включая свежий #3071 — тот синхронизирует `/opt/gendesign`) и не покрывал ни один бэкап. **Практический смысл:** при потере хоста БД и репозитории восстановятся, а конфигурация — нет. Пришлось бы вручную воссоздавать `docker-compose.yml` и заново регистрировать три раннера. Для переезда это особенно неприятно: **Forgejo остаётся на Beget**, то есть он и есть та машина, с которой всё будет подниматься, если что-то пойдёт не так. Косвенное подтверждение, что каталог правится руками и без истории — рядом лежат три самодельных снимка вместо version control: ``` runner-compose.yml.bak runner-compose.yml.bak.1779049805 runner-compose.yml.bak.before-runner3 ``` ## Что сделано Третий артефакт `forgejo-config_<ts>.tar.gz` рядом с дампом и repo-бандлом, уезжает в S3 тем же циклом. **Что намеренно НЕ включено:** секрет-файл режима 600 и `runner*/data/` с регистрационными токенами. Они остаются ручным off-box пунктом владельца — тем же, что рантайм-секреты в приёмке #2203. Логика простая: раннеры при восстановлении перерегистрируются из UI за пару минут, а компоуз-файл руками не восстановишь. **Мягкая деградация:** не собрался — `WARN` и продолжаем без него. Бэкап БД и репозиториев не должен теряться из-за 5 КБ конфига. Проверки те же две, что у repo-бандла — не «объём», а «собрался и читается». ## Test plan Прогнал ровно ту же команду `tar` против **настоящего каталога на проде**, read-only, боевой бэкап не тронут: - [x] `tar` код возврата **0** - [x] В архиве **ровно 2 файла**: `docker-compose.yml`, `runner-compose.yml` - [x] **1070 байт**, архив читается (`tar -tzf`) - [x] **Секрет-файла внутри нет** (0 совпадений), **каталога `data/` внутри нет** (0) — то есть ни секретов, ни дублирования repo-бандла - [x] Раскрытие `${config_out:+"$config_out"}` в цикле выгрузки: пусто → 2 файла, задано → 3 - [x] `bash -n` чист - [x] Временный тестовый архив удалён ## Побочно — к #3030 Заодно выяснилось, почему пункт «лимиты выставлены» там нельзя закрыть через PR целиком: **Forgejo (2.235 ГиБ, самый крупный потребитель) и три раннера описаны файлами вне git**. Выставить им `mem_limit` можно только правкой этих файлов на хосте — это не код, это ручная работа на проде. В репозитории лимитами управляемы только `docker-compose.prod.yml` и `docker-compose.obsidian.yml`. Refs #2203, #3057, #3030
lekss361 added 1 commit 2026-08-24 03:47:55 +00:00
feat(ops): бэкапить конфигурацию Forgejo, а не только его содержимое
All checks were successful
CI / changes (pull_request) Successful in 9s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
03a600db65
backup-forgejo.sh забирал БД и голые репозитории — то есть СОДЕРЖИМОЕ
Forgejo, но не то, ЧЕМ оно поднимается.

Компоуз-файлы Forgejo и раннеров живут в /home/gendesign/forgejo/, ВНЕ
репозитория: `git rev-parse` там отвечает "not a git repository". Их не
трогает ни один деплой (включая #3071 — тот синхронизирует /opt/gendesign)
и не покрывал ни один бэкап.

Практический смысл: при потере хоста БД и репозитории восстановятся, а
конфигурация — нет. Пришлось бы вручную воссоздавать docker-compose.yml и
заново регистрировать три раннера. Для переезда это особенно неприятно:
Forgejo ОСТАЁТСЯ на Beget, то есть он и есть та машина, с которой всё
будет подниматься, если что-то пойдёт не так.

Косвенное подтверждение, что каталог правится руками и без истории:
рядом лежат runner-compose.yml.bak, .bak.1779049805, .bak.before-runner3 —
три самодельных снимка вместо version control.

Что НЕ включено намеренно: секрет-файл режима 600 и runner*/data/ с
регистрационными токенами. Они остаются ручным off-box пунктом владельца —
тем же, что рантайм-секреты в приёмке #2203. Раннеры при восстановлении
перерегистрируются из UI за пару минут; компоуз-файл руками не
восстановишь.

Проверки те же две, что у repo-бандла (не «объём», а «собрался и
читается»), плюс мягкая деградация: не собрался — WARN и продолжаем без
него, бэкап БД и репозиториев не теряем из-за 5 КБ конфига.

Проверено на настоящем каталоге прода (read-only, боевой бэкап не
тронут):
  - tar код 0, ровно 2 файла: docker-compose.yml, runner-compose.yml
  - 1070 байт, архив читается
  - секрет-файла внутри нет, каталога data/ внутри нет
  - раскрытие ${config_out:+...} в цикле выгрузки: пусто -> 2 файла,
    задано -> 3
  - bash -n чист

Refs #2203, #3057
lekss361 merged commit f52601de41 into main 2026-08-24 03:49:58 +00:00
lekss361 deleted branch feat/backup-forgejo-config 2026-08-24 03:49:58 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3073
No description provided.