тгТихая грань
ЗАМЕТКА · ПУБЛИКАЦИЯ

Атомарная публикация статического сайта

Проверенный каталог переключается целиком, а предыдущая версия остаётся для отката.

Проверено: 2026-02-21

Почему нельзя писать поверх

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

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

Переключение указателя

На POSIX удобно хранить неизменяемые выпуски в отдельном каталоге, а public делать символьной ссылкой на выбранный выпуск. Новую ссылку создают под временным именем и заменяют public одним os.replace. Rename имени ссылки атомарен на поддерживаемой локальной файловой системе. Обычная замена непустого каталога через os.replace такой возможности не даёт.

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

Какая гарантия получается

Атомарность переключения не означает, что все HTTP-запросы одного браузера видят один выпуск. Документ мог прийти до переключения, а CSS — после. Для строгой согласованности ресурсов используют имена с хешами или версионированные пути, сохраняя старые ресурсы достаточно долго. Для небольшого справочника стабильный совместимый CSS снижает риск, но не создаёт транзакцию браузерной сессии.

Устойчивость после внезапного отключения питания — отдельный вопрос. Для неё нужны flush и fsync файлов и каталогов в подходящем порядке, а реальные гарантии зависят от файловой системы и накопителя. Проверка ссылок доказывает логическую полноту дерева, но не подтверждает crash durability. Эти свойства следует описывать раздельно.

Настройка статической выдачи

Для nginx укажите корень public и правило try_files, которое завершает неизвестный путь кодом 404. Отдельный error_page может показать подготовленный документ, сохраняя статус ошибки. Для Caddy аналогично нужны file_server и обработчик ошибок. Проверьте оба случая по HTTP: существующая страница должна вернуть успешный статус, отсутствующая — ошибочный. Перенаправление любого неизвестного пути на главную скрывает битые ссылки и не подходит этому справочнику. Также проверьте доступность ресурсов после переключения ссылки и права чтения на родительских каталогах. Символьная ссылка не помогает, если серверу запрещено пройти к её цели. Конфигурация выдачи остаётся отдельным исходником развёртывания и не должна создаваться из непроверенного текста новой статьи.

Откат и контроль

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

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

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

Связанные материалы