Учебник веб-разработки
Разделы учебника
На этой странице

XI. DevOps

Лаборатория: какие свидетельства подтверждают релиз

Оглавление · CI/CD · Готовность · Откат и восстановление

Задача: по разрозненным результатам установить, что проверено, что применено и чего пока нельзя утверждать. Упражнения вымышленные и не выполняют deploy.

Нельзя свести релиз к одному зелёному флагу

Состояние представим как (C,A,E,D,O): C — проверенный commit, A — выбранные артефакты, E — конфигурация среды, D — данные, O — наблюдения. Связи между ними требуют свидетельств. Например, O с HTTP 200 без идентичности A подтверждает ответ endpoint, но не то, что ответил новый релиз.

Исходник схемы
flowchart TD
  Commit["Commit и точный run"] --> Check["Результат проверок"]
  Commit --> Images["Digest опубликованных образов"]
  Images --> Applied["Образы работающих контейнеров"]
  Config["Конфигурация и данные"] --> Applied
  Applied --> Probe["Наблюдение: endpoint или сценарий"]
  Probe --> Report["Утверждение с границей проверки"]
СвидетельствоДопустимый выводСледующий пробел
Локальные тесты в worktreeПроверено локальное состояниеCommit, удалённый CI, publication
check success для выбранного SHAЭти проверки прошли для runРезультат images/deploy
Digest получен после pushЭтот image опубликованИспользует ли его VPS?
Контейнер запущен с image referenceПрименён выбранный артефактГотовность нужной операции
HTTPS health 200Проверенный endpoint отвечаетИдентичность релиза, CMS/media, UI
Ручной editor workflowЭтот сценарий выполненОстальные сценарии и долговременная доступность

Список не требует выполнять все проверки после любой опечатки в Markdown. Проверки выбирают под изменение; формулировка результата должна соответствовать реально собранным свидетельствам.

Локальный опыт: имя артефакта и хеш байтов

Следующий пример использует только Node 24 и память. Это модель content addressing, а не сборка Docker image или проверка подписи. tag — условное изменяемое имя; хеш вычисляется по конкретным байтам.

node --input-type=module <<'JS'
import assert from "node:assert/strict";
import { createHash } from "node:crypto";

const digest = (bytes) => createHash("sha256").update(bytes).digest("hex");
const first = Buffer.from("<h1>Учебник: версия 1</h1>");
const second = Buffer.from("<h1>Учебник: версия 2</h1>");
const checkedDigest = digest(first);
const registry = new Map([["lesson:current", first]]);
registry.set("lesson:current", second);

assert.equal(digest(first), checkedDigest);
assert.notEqual(digest(registry.get("lesson:current")), checkedDigest);
console.log("Имя то же; байты изменились; хеш обнаружил расхождение");
JS

Одинаковое имя не означает одинаковые байты. Для реального image digest относится к объекту manifest/index registry; это не просто sha256 tar-каталога исходников. Идентификатор помогает выбрать артефакт, но не подтверждает источник доверия или полноту его проверок. Image digest Docker.

Опыт 1: зелёный run, старый frontend

Вымышленные свидетельства:

  • main/commit A: check success, images success, deploy success.
  • release.sh сообщил: CMS prepared, CONTENT_READY is false.
  • current указывает на релиз P; cms-current и prepared — на A.
  • /api/health отвечает 200.

Сначала напишите свой вывод, затем сравните: новые образы опубликованы и CMS подготовлена, но frontend не переключён. Успех deploy job соответствует предусмотренной ветке подготовки. Нельзя утверждать, что новый web работает, только по health. Следующий шаг в настоящей процедуре зависит от явного импорта и проверки содержимого; в рамках упражнения ничего не импортируем.

Опыт 2: красный run после публикации

Вымышленные свидетельства:

  • images опубликовал web и Strapi; deploy запустил CMS.
  • Применение web завершилось, но HTTPS content-health получил 503.
  • Скрипт попытался вернуть прежние web/Caddy; SSH затем оборвался.

Ответ: образы опубликованы, среда могла измениться, успешный rollback не подтверждён. Нужно установить фактические версии компонентов и состояние сервисов. Красный job не доказывает отсутствие изменений, а сообщение о попытке rollback — его успех. Возврат web/Caddy не возвращает БД и Strapi; сначала нужна совместимость.

Исходник схемы
flowchart LR
  Failure["Run завершился ошибкой"] --> Inspect["Установить фактическое состояние"]
  Inspect --> Compatible["Оценить совместимость кода и данных"]
  Compatible --> Choice["Продолжить релиз / вернуть код / восстановить данные"]
  Choice --> Verify["Проверить выбранный результат"]

Опыт 3: поменялся контент, commit тот же

Вымышленные свидетельства: rerun main/A успешен, редактор изменил новость между попытками; CMS_BUILD_ID всё ещё A. Образ использует build cache.

Ответ: commit не изменился, но внешний вход изменился. Нельзя по успеху rerun утверждать, что новое содержимое попало в статический слой образа. Проверяют, был ли выполнен соответствующий RUN, какой артефакт получен и что обслуживает страница после runtime-ревалидации. ISR может обновить страницу без нового image; поэтому её текст тоже не идентифицирует image. См. рендеринг.

Опыт 4: новое staging и выпущенный релиз

Вымышленные свидетельства: production успешно применил staging generation G1, но release-ветка уже получила новый commit и staging G2. Controller повторяет poll.

Ответ: production остаётся на проверенных digest G1. Охлаждать можно только совпавшую generation G1; новый staging G2 этим выпуском останавливать нельзя. Успех публикации образа G2 не означает новый production release.

Чтение настоящего pipeline без запуска

Откройте .sourcecraft/ci.yaml, environments.py и production.py. Отметьте event/ref guard, needs, границу IAM, SHA/digest capsule, общий lock, критерий успеха и recovery. YAML описывает предусмотренное поведение; состояние живого VPS из него не следует.

В деплое есть команды чтения run. Связывайте запуск с commit и проверяйте требуемые tasks, включая skipped. Не запускайте workflow и не изменяйте credentials ради упражнения.

Составьте отчёт

Для каждого опыта напишите три предложения: что подтверждено; что осталось неизвестным; какое следующее наблюдение уменьшит неопределённость. Пример: «Image опубликован под digest D. Применение на VPS не подтверждено. Нужно сверить образ работающего контейнера и выполнить выбранный сценарий». Не заменяйте неизвестное предположением ради короткого слова «готово».