Перейти к содержанию

Артефакт, конфигурация и идентификатор версии

В предыдущем уроке мы отделили исходники от артефакта и действующего окружения. Теперь уточним, что именно входит в артефакт release-lab. Это потребуется при передаче кандидата на staging, при повторной публикации на Beget и при возврате прежней версии. Хорошо подготовленный результат позволяет ответить на вопрос «что сейчас размещено» даже после того, как окно редактора закрыто.

Пусть генератор уже создал дерево public/. Мы не переписываем генератор из курса про Markdown и не предполагаем, что его устройство совпадает с инструментами ProfessorWeb. Для новой серии достаточно готового дерева. Перед упаковкой добавим описание выпуска и небольшой публичный индикатор версии, а настройки сервера оставим за пределами дерева, которое будет отдавать Nginx или хостинг.

Где заканчивается публичная часть

Рассмотрим следующую структуру. Каталог artifact станет содержимым доставляемого выпуска, а его public — корнем сайта. Файл release.json расположен рядом с корнем. Он нужен издателю и не должен случайно превращаться в страницу. В health.json включим только короткий номер: посетителю и системе наблюдения не требуется узнавать внутренний путь рабочего компьютера или полный список зависимостей.

artifact/
  release.json
  public/
    index.html
    catalog/index.html
    articles/markdown-guide.html
    my/legacy/first.php
    assets/site.r1.css
    404.html
    health.json
    robots.txt
    sitemap.xml

Дерево показывает не набор файлов для ручного редактирования на сервере, а завершённый результат. Если исправить файл внутри уже названного артефакта, паспорт перестанет точно описывать этот результат. Поэтому правку возвращают в исходники, заново получают готовое дерево и присваивают новый идентификатор. Исключением бывает аварийное вмешательство, однако и его приходится фиксировать отдельно: прежний номер больше нельзя считать доказательством неизменности.

Публичность определяется корнем веб-сервера, а не названием файла. Секретный файл с точкой в начале имени может оказаться доступным при ошибочной конфигурации. Надёжнее вообще не включать настройки с паролями в артефакт. По этой же причине резервный архив не кладут внутрь public/, даже если кажется, что посетитель не догадается о его имени. У каждого файла должно быть понятное место и назначение.

Паспорт, который можно проверить

Для первых примеров используем читаемое имя r2. В автоматической упаковке оно будет заменено идентификатором вида p123-a1b2c3d4: номер конвейера и короткий идентификатор исходников позволяют связать файлы с конкретной сборкой. Само сочетание не является криптографическим доказательством; контрольная сумма архива отвечает на другой вопрос — совпадают ли переданные байты с сохранённым архивом.

{
  "release": "r2",
  "project": "release-lab",
  "public_root": "public",
  "required_paths": [
    "/", "/catalog/", "/articles/markdown-guide.html",
    "/my/legacy/first.php", "/404.html"
  ]
}

Не будем записывать вымышленную дату фактической публикации. Паспорт может содержать время упаковки, когда упаковка действительно выполняется, но это не время переключения сервера. Одно и то же содержимое способно попасть на staging сегодня, а на основной сайт через неделю. Журнал развёртывания запишет каждое событие отдельно. При нескольких окружениях такое разделение позволяет отличить старый, но сознательно выбранный выпуск от ошибки доставки.

Создадим ожидаемое содержание публичного индикатора: {"release":"r2"}. После будущей публикации проверка получает этот файл через тот же домен, который используют посетители. Если ответ содержит r1, возможны неверный корень, неправильная привязка домена или сохранённая копия в кеше. Сам по себе индикатор не доказывает полноту статей и изображений. Он лишь даёт первую точку привязки, после которой проверяют обязательные маршруты и содержание страницы.

Что относится к конфигурации окружения

Корень сайта, сертификат, ограничения доступа и адрес базы описывают окружение. Для статического стенда у production будет публичный доступ, а у staging — серверная аутентификация. Мы переносим один артефакт, но не переносим вместе с ним пароль от тестового окружения или ключ сертификата. Иначе публичный сайт может остаться закрытым, а staging — неожиданно открыться после следующей загрузки.

В то же время некоторые настройки генератора влияют на сам HTML. Например, абсолютный canonical или адрес в Sitemap появляется в файлах до публикации. Для проверяемого производственного кандидата мы сохраняем основной адрес https://example.com, даже если просматриваем результат на закрытом staging.example.com. При иной задаче, например независимом публичном тестовом сайте, можно собирать специальный результат с другой базой URL. Тогда это уже другой артефакт, и сравнивать его с производственным следует осознанно.

В Nginx директива root связывает запрос с файловым деревом. Её значение не обязано повторять название домена или исходной папки проекта. Это позволяет держать конфигурацию постоянной, меняя выбранный выпуск через ссылку current. Подробно настроим обработку путей в шестом уроке. Официальное описание root и обработки файлов.

Доставка не должна менять содержание

Предположим, что архив кандидата скачали из CI, передали по защищённому соединению и распаковали в новый каталог. До переключения нужно убедиться, что получился уровень release/public/index.html, а не случайное вложение release/artifact/public/index.html. Неверная вложенность часто выглядит как ошибка Nginx, хотя сервер честно ищет файл в указанном корне. Паспорт и небольшое дерево обязательных файлов помогают заметить это до открытия сайта.

При наличии файла контрольной суммы будущий читатель может сопоставить архив перед распаковкой. Такая проверка обнаруживает повреждение или передачу другого файла, но не проверяет качество текста, правильность ссылок или добросовестность источника архива. Сумма должна поступать из доверенного выпуска, а не из случайного каталога рядом с подменённым архивом. Эти границы важны: технический контроль полезен именно тогда, когда понятно, что он подтверждает.

sha256sum -c release-r2.tgz.sha256
tar -tzf release-r2.tgz

Команды приведены для будущего стенда; их вывод в этом уроке не измерялся. Первая должна подтвердить совпадение байтов, вторая — позволить увидеть структуру без распаковки. При упаковке недоверенного содержимого дополнительно проверяют пути, ссылки и владельцев файлов: архив нельзя без разбора раскрывать с административными правами поверх действующего сайта. В нашей серии артефакт формируется из контролируемого публичного дерева, а публикация идёт в отдельный каталог.

После этого урока кандидат стал переносимым объектом: у него есть публичная часть, непубличный паспорт и узнаваемый номер. Однако наличие файлов ещё не определяет, куда придёт запрос браузера. В следующем уроке разберём домен, DNS и привязку имени к сайту.