🧙 Садовник: уточнил шаги, добавил проверки и обоснования. Примите, если полезно.
#1Предлагаемые изменения · v1 → предложение
−131−¶ **Когда применять.** Получено оповещение о недоступности веб-сервиса либо отказ замечен самостоятельно.
2−
3− Порядок построен так, чтобы каждый шаг **отсекал целый класс причин**, а не проверял наугад. Пропуск первых трёх шагов — самая частая потеря времени: диагностируют приложение, когда недоступна сеть.
41## 1. Подтверждение оповещения
521. Проверить сетевую доступность рабочей станции
63 Прежде чем диагностировать сервер, убедиться, что маршрут до него существует.
74 $ curl -s -o /dev/null -w '%{http_code}\n' https://github.com
85 why: Обрыв связи у рабочей станции внешне неотличим от отказа сервера. Диагностика и устранение при этом принципиально разные.
96 - [ ] Код 200 — связь есть, продолжать
107 - [ ] Пустой ответ — устранять связь, сервер ни при чём
1182. Проверить работоспособность системы мониторинга
129 Открыть status.equiply.ru. При её отказе в Telegram поступает отдельное оповещение от watchdog.
1310 $ curl -s -o /dev/null -w '%{http_code}\n' https://status.equiply.ru
1411 why: uptime-kuma и ntfy размещены на одном сервере. При его отказе замолкают оба, и отсутствие оповещений становится неотличимо от штатной работы.
1512 - [ ] Мониторинг отвечает — оповещению можно доверять
1613 - [ ] Не отвечает — наблюдение за сайтами прекращено, это самостоятельный инцидент
17143. Проверить сервис из второй точки [recommended]
1815 Мониторинг наблюдает мир из одной точки. Рабочая станция — вторая независимая.
1916 $ curl -sS -o /dev/null -w 'код %{http_code}, время %{time_total}s\n' https://ДОМЕН
2017 why: Недоступность сервиса и недоступность маршрута от сервера мониторинга — разные инциденты, требующие разных действий.
2118 - [ ] Результат совпал с оповещением — отказ подтверждён
2219 - [ ] Сервис открывается — проверять маршрут от мониторинга, а не сервис
23−¶ **Масштаб определяет объект восстановления.** Один домен — восстанавливается приложение. Несколько доменов одного сервера — восстанавливается сервер, поочерёдная проверка сайтов бессмысленна.
2420## 2. Оценка масштаба
25214. Определить масштаб по заголовку оповещения
2622 Заголовок содержит ответ: «netcup: не отвечают 3 из 16 сайтов» либо «ttinv.ru не отвечает».
2723 why: Группировка по серверу введена именно для этого: при отказе netcup недоступны четырнадцать доменов, и четырнадцать раздельных оповещений скрыли бы существо инцидента.
2824 - [ ] Указан сервер — переходить к серверу
2925 - [ ] Указан домен — переходить к его проекту
30265. Уточнить состав сервера по реестру [recommended]
3127 $ python3 -c "import yaml,pathlib; d=yaml.safe_load(pathlib.Path('/home/mike/Projects/arch-hq/registry/servers.yml').read_text()); [print(s['name'], [x['host'] for x in (s.get('sites') or [])]) for s in d['servers']]"
3228 why: Работоспособность соседних сервисов исключает отказ сервера целиком и вдвое сужает область поиска.
3329## 3. Идентификация проекта
34306. Определить репозиторий по домену
3531 Задача уже создана в репозитории затронутого проекта, в её тексте перечислено всё семейство.
3632 $ repo-for --all ДОМЕН
3733 why: Домену соответствует несколько репозиториев: devon-pro — три, setfork — шесть. Без полного перечня отказ серверной части ищут в клиентской.
3834 - [ ] Возвращён arch-hq — репозиторий не установлен, диагностика только по логам
3935## 4. Подключение к серверу
40367. Подключиться по SSH
4137 Параметры доступа находятся в ~/.ssh/config и порождаются из реестра серверов.
4238 $ ssh netcup # либо servicest4, brave
4339 why: Ключи и конфигурация подготовлены заранее — поиск доступов во время инцидента исключён.
4440 - [ ] Подключение не устанавливается — перейти к шагу о недоступности сервера
45418. Действия при недоступности SSH [optional]
4642 Остаётся панель управления хостингом и перезагрузка. Ссылки на панели в реестре ОТСУТСТВУЮТ — известный пробел.
4743 why: Перезагрузка — крайняя мера: она уничтожает состояние, по которому устанавливается причина. Применять после исчерпания остальных способов.
4844## 5. Установление причины
49459. Выявить нездоровые контейнеры
5046 $ docker ps --format '{{.Names}}\t{{.Status}}' | grep -v healthy
5147 why: Контейнер может находиться в состоянии Up и при этом не обслуживать запросы; признак healthy эту разницу показывает.
5248 - [ ] Контейнер отсутствует в выводе — он не запущен, проверить docker ps -a
534910. Изучить журнал отказавшего контейнера
5450 $ docker logs --tail 200 --timestamps КОНТЕЙНЕР 2>&1 | tail -60
5551 why: Причина отказа фиксируется в конце журнала; начало занято загрузкой зависимостей.
5652 - [ ] Искать строки error, failed, denied, exit code
5753 - [ ] Журнал пуст — проверить docker inspect КОНТЕЙНЕР --format '{{.State}}'
585411. Проверить дисковое пространство и память [recommended]
5955 $ df -h / && free -m && docker system df
6056 why: Значительная доля отказов без очевидной причины вызвана исчерпанием дискового пространства. Проверка обходится дешевле построения гипотез.
6157 - [ ] Свободно менее 10% — причина установлена
625812. Проверить связь с недавним развёртыванием [recommended]
6359 $ docker ps --format '{{.Names}}\t{{.RunningFor}}' | sort -k2
6460 why: Первый вопрос при отказе — не вызван ли он последним изменением. Недавно запущенный контейнер отвечает на него немедленно.
65−¶ **Дальнейшие действия принимает человек.** Ниже перечислено допустимое, а не предписанное. Автоматическое восстановление промышленной среды не применяется: видов отказа много, а сценарий автоматического исправления один.
6661## 6. Восстановление
676213. Перезапустить сервис [optional]
6863 Наименее затратное действие, если причина в зависшем процессе, а не в коде.
6964 $ docker compose restart СЕРВИС
7065 why: Тома с кэшами сохраняются при перезапуске и уничтожаются при пересоздании.
7166 - [ ] НЕ применять docker compose down — приводит к потере томов и кэшей
7267 - [ ] НЕ применять docker system prune без фильтра
736814. Внести исправление в код [optional]
7469 Исправить в локальной копии, отправить в main. Развёртывание выполняется автоматически.
7570 why: Правка непосредственно на сервере утрачивается при следующем развёртывании и не попадает в историю изменений.
7671## 7. Подтверждение восстановления
777215. Дождаться оповещения о восстановлении
7873 Мониторинг фиксирует восстановление и направляет отдельное сообщение.
7974 why: Без подтверждения возможно продолжение работ над сервисом, восстановившимся самостоятельно, и ошибочное отнесение результата к принятым мерам.
8075 - [ ] Оповещение не поступило в течение 5 минут — проверить сервис вручную
817616. Закрыть задачу с указанием причины
8277 В том репозитории, где она создана. Указать установленную причину и выполненные действия.
8378 $ gh issue close НОМЕР -R mikey-semy/РЕПОЗИТОРИЙ -c 'причина: … ; выполнено: …'
8479 why: Закрытые задачи образуют статистику отказов. По ней через месяц видно, какие отказы повторяются, — а это и определяет, что подлежит исправлению в первую очередь.
85−¶ **Не реализовано на текущий момент** — перечень приводится намеренно:
86−
87− - ссылки на панели управления хостингом для случая недоступности SSH
88− - учёт ложных срабатываний: каждое падение считается новым
89− - окно тишины на время развёртывания — собственное изменение способно вызвать оповещение
90− - приоритет по владельцу: простой клиентского сервиса равнозначен собственному
91−
92− Пересмотр — после месяца эксплуатации. Фиксировать следует не то, что сработало, а то, чего недоставало в момент инцидента.
Ревью