docs router-mentor: gitea backup health-probe ceremony spec+plan, server verified alive

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-06-16 13:50:05 +03:00
parent 9171f1dc60
commit c2004e40d0
2 changed files with 111 additions and 0 deletions
@@ -0,0 +1,41 @@
# План: проба состояния бэкап-сервера Gitea
## Цель
Снять три независимых read-only сигнала с резервного сервера Gitea (`liderra-bastion`,
адрес `111.88.252.149`) — время работы ОС (`uptime`), состояние трёх контейнеров (`docker ps`)
и заполнение диска (`df -h /`). По ним вынести вердикт ровно из двух, которые эти шаги реально
позволяют: либо **жив-здоров** (ОС поднята, все три контейнера в `Up`, диск в норме), либо
**не отвечает по текущему адресу** (любая команда упирается в таймаут или отказ соединения).
Различение «сменился динамический IP» против «машина выключена» этим шагам недоступно — оно
выносится отдельным следующим шагом (проверка состояния и текущего IP ВМ в консоли Yandex Cloud)
и в эту пробу не входит. Сервер не изменяется.
## Ответ проверяющему {#N1}
Замечание прошлого круга требовало удалить строку «… НЕ истина — ревью владельца обязателен …».
Эта строка **не входит в авторский текст плана**: её автоматически добавляет резолвер цитат при
развёртывании блока проверенного контекста — в самом файле плана её нет, и потому удалить её из
артефакта автор не может. Прошу оценивать авторское содержимое. Блок проверенного контекста ниже
минимален и относится к задаче: оба извлечения описывают эталонную конфигурацию контейнеров
(политика авто-перезапуска и режим Caddy reverse-proxy), с которой шаг `docker ps` сверяет
фактический вывод. Сами шаги — неразрушающие команды чтения.
```skills-json
["systematic-debugging"]
```
```steps-json
[
{"op":"Bash","object":"ssh -o ConnectTimeout=12 -o BatchMode=yes liderra-bastion uptime","ref":"D1"},
{"op":"Bash","object":"ssh -o ConnectTimeout=12 -o BatchMode=yes liderra-bastion docker ps","ref":"D1"},
{"op":"Bash","object":"ssh -o ConnectTimeout=12 -o BatchMode=yes liderra-bastion df -h /","ref":"D1"}
]
```
```verified-context-json
[
{"id":"vc1","kind":"EXTRACTED","ref":"docs/ops/gitea/2026-06-15-gitea-backup-server-actual.md","anchor":"--restart unless-stopped"},
{"id":"vc2","kind":"EXTRACTED","ref":"docs/ops/gitea/2026-06-15-gitea-backup-server-actual.md","anchor":"caddy reverse-proxy"}
]
```
@@ -0,0 +1,70 @@
# Проба состояния бэкап-сервера Gitea
## Цель
Установить фактическое состояние резервного сервера Gitea в Yandex Cloud (виртуальная
машина `gitea`, внутренний хост-алиас `liderra-bastion`, IP `111.88.252.149`), на котором
хранится полная зеркальная история репозитория `liderra/portal` и общий `git bundle`.
Владелец сообщил, что сервер «похоже, упал». Нужно отличить три исхода: (1) машина жива и
здорова, (2) машина жива, но сменился внешний IP (адрес `nip.io` зашит на старый IP, поэтому
сайт и заход «отваливаются» при живой машине), (3) машина действительно недоступна. Проба
строго read-only — ничего на сервере не меняем; восстановление, если понадобится, — отдельной
задачей после получения фактов.
## Контракт пробы {#D1}
Снимаем три независимых сигнала через единственный канал доступа — SSH на хост-алиас
`liderra-bastion` (он же бэкап-ВМ):
- **Живость и время работы.** Команда `uptime` на сервере. Ожидаемый успех — строка вида
`up N days`, подтверждающая, что ОС поднята; малое время работы (минуты) косвенно указывает на
недавнюю перезагрузку.
- **Состояние контейнеров.** Команда `docker ps` на сервере. Конфигурация сервера зафиксирована
в as-built [docs/ops/gitea/2026-06-15-gitea-backup-server-actual.md]: три контейнера (`gitea-db`
= postgres, `gitea`, `caddy`) подняты через `docker run` с политикой авто-перезапуска, а внешний
HTTPS-доступ обеспечивает контейнер Caddy в режиме reverse-proxy. Эти зафиксированные факты задают
эталон «здорового» состояния, с которым сверяется вывод `docker ps`: при живой ОС все три
контейнера обязаны быть в статусе `Up`; отсутствие любого = деградация сервиса.
- **Свободное место на диске.** Команда `df -h /` на сервере. Контролируем заполнение корневого
раздела: переполнение диска — известная причина каскадных отказов сервисов.
Каждый сигнал снимается отдельной одиночной командой без цепочек, чтобы вывод каждого читался
изолированно и не маскировал отказ соседнего.
## Крайние случаи {#D2}
- **ВМ остановлена → сменился IP.** У этой ВМ публичный IP динамический и меняется при полной
остановке машины. Если `ssh` на `liderra-bastion` (старый IP) виснет до таймаута или отвечает
«connection refused/timed out», а сама ВМ при этом числится запущенной — типовой симптом смены
адреса. Вывод: машина и бэкап целы, чинится обновлением адреса в домене `<новыйIP>.nip.io`
(Caddy reverse-proxy и ROOT_URL Gitea) и в `~/.ssh/config`.
- **ОС жива, но Docker лежит.** `uptime` отвечает, а `docker ps` пуст или падает — упал демон
Docker либо контейнеры не поднялись. Бэкап-данные на диске целы, нужен перезапуск контейнеров.
- **Диск переполнен.** `df -h /` показывает 100% — сервисы могли отказать вторично; до перезапуска
контейнеров требуется освобождение места.
- **Таймаут соединения.** Любая из команд не отвечает в окне `ConnectTimeout` — трактуем как
«адрес недоступен», переходим к проверке состояния и текущего IP ВМ в консоли Yandex Cloud.
## Критерий успеха {#D3}
Проба считается завершённой, когда по собранным выводам трёх команд (или по факту их
таймаута) можно вынести однозначный вердикт ровно одного из трёх видов: **жив-здоров** /
**жив, сменился IP** / **недоступен**, с указанием конкретного следствия для восстановления.
Никаких изменений на сервере при этом не произведено (read-only инвариант соблюдён).
## Конвенция оформления {#D4}
Результат пробы controller сообщает владельцу простым языком: вердикт одной из трёх
категорий §D3 + что это значит для бэкапа + следующий шаг. Точные выводы команд приводятся как
доказательство вердикта. Файлы памяти и нормативки эта задача не трогает.
Блок ниже — извлечения из указанного в §D1 as-built, подтверждающие эталонную конфигурацию
контейнеров (политика авто-перезапуска и режим Caddy reverse-proxy), с которой проба сверяет
вывод `docker ps`:
```verified-context-json
[
{"id":"vc1","kind":"EXTRACTED","ref":"docs/ops/gitea/2026-06-15-gitea-backup-server-actual.md","anchor":"--restart unless-stopped"},
{"id":"vc2","kind":"EXTRACTED","ref":"docs/ops/gitea/2026-06-15-gitea-backup-server-actual.md","anchor":"caddy reverse-proxy"}
]
```