Структурированные каталоги проекта отделены от защищённого блока секретов
DevOps

Структура репозитория сайта перед публикацией

Организуем исходники, публичные файлы, конфигурацию, скрипты и результат сборки так, чтобы проект было безопасно проверять и публиковать.

Содержание

Репозиторий — каталог проекта, историю которого хранит Git. По его структуре должно быть понятно, где редактировать сайт, какой командой проверить изменения и какой каталог публиковать. Иначе собранные файлы смешиваются с исходниками, а локальный кеш или пароль легко принять за часть проекта.

Что должно лежать в репозитории

Держите исходники, публичные статические файлы, конфигурацию и эксплуатационные скрипты в отдельных каталогах. Коммитьте manifest и lock-файл, но не node_modules, локальные кеши, .env и приватные ключи. Результат сборки должен создаваться одной командой и не редактироваться вручную. В README зафиксируйте установку, проверку, build, deploy и rollback.

Разделите файлы по назначению

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

website/
├── app/                    # исходный код и шаблоны
├── assets/                 # изображения, шрифты и стили
├── public/                 # файлы, копируемые без обработки
├── config/                 # несекретная конфигурация
├── scripts/                # проверка и публикация
├── tests/                  # автоматические тесты
├── package.json            # команды и зависимости
├── package-lock.json       # зафиксированное дерево зависимостей
├── .gitignore
└── README.md

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

Используйте предсказуемые имена

Имя модуля, теста и связанного ресурса должно позволять найти их без догадок. Не создавайте рядом final, final-new и final-2: Git уже хранит версии. Для временного эксперимента используйте ветку или явно игнорируемый локальный каталог.

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

Считайте каталог public общедоступным

Всё внутри public считается предназначенным для публикации. Туда подходят общедоступные изображения, шрифты и явно требуемые служебные файлы. Не кладите туда:

  • .env и конфигурацию с паролями;
  • резервные копии и архивы;
  • рабочие исходники графики;
  • приватные ключи и сертификаты с private key;
  • внутренние инструкции и списки адресов;
  • дампы базы данных.

Проверьте итоговый каталог сборки: файл может попасть туда не только из public, но и через импорт или пользовательский build-скрипт.

Редактируйте исходник, а не результат сборки

Редактируемый шаблон или компонент находится в исходниках, а готовые HTML, CSS и JavaScript создаются сборщиком. Правка сгенерированного HTML исчезнет при следующем build. Поэтому источник истины — исходный файл, а каталог результата — одноразовый артефакт.

То же относится к CSS и JavaScript с хешированными именами. Не переименовывайте их вручную на сервере: ссылки уже записаны в HTML. Исправьте исходник, повторите сборку и опубликуйте новый целостный результат.

Исключите локальные и секретные файлы

Создайте .gitignore в корне репозитория. Пример исключает зависимости, результат сборки, локальные переменные, ключи и журналы, но сохраняет .env.example с пустыми образцами настроек:

node_modules/
build/
.cache/
.env
.env.*
!.env.example
*.key
*.pem
*.log

Добавляйте только действительно производные или локальные файлы. Слишком широкий шаблон вроде config/ может скрыть обязательную несекретную конфигурацию.

Важно: .gitignore влияет на неотслеживаемые файлы. Если секрет уже добавлен в Git, новое правило не убирает его из истории. Значение нужно отозвать, затем отдельно решить вопрос с историей и копиями.

После сохранения .gitignore проверьте, какое правило сработало и какие файлы Git уже отслеживает. Команды выполняются в корне репозитория и ничего не удаляют:

git status --short --ignored
git check-ignore -v .env build/index.html
git ls-files

Последняя команда не должна показывать .env, private key или node_modules.

Храните описание и точные версии зависимостей

package.json описывает допустимые зависимости и команды проекта. Такой файл называют манифестом. package-lock.json фиксирует конкретное дерево установки. В корне проекта установите его без автоматического изменения lock-файла:

npm ci

Если manifest и lock-файл расходятся, npm ci должен завершиться ошибкой, а не незаметно изменить lock-файл. Не исправляйте расхождение на production. Обновите зависимости локально, проверьте diff и закоммитьте согласованную пару файлов.

Не храните node_modules в Git: каталог зависит от платформы, велик и создаётся пакетным менеджером. Сборочные сценарии зависимостей способны выполнять код, поэтому установка должна идти непривилегированным пользователем и из проверенного lock-файла.

Разделите конфигурацию и секреты

В репозитории допустимы:

  • ID категорий и отображаемые названия;
  • публичный адрес сайта;
  • несекретные feature flags;
  • .env.example с названиями переменных;
  • схема проверки обязательных значений.

Отдельно передаются пароли, токены, private keys и production credentials. В коде должна быть понятная ошибка, если обязательного значения нет. Не подставляйте тестовый пароль по умолчанию: это превращает неправильную конфигурацию в скрытую уязвимость.

Храните эксплуатационные сценарии рядом с кодом

scripts/deploy.sh, rollback.sh и проверка результата должны проходить review и версионирование. Хороший deploy-скрипт:

  • прекращает работу при ошибке;
  • проверяет чистое состояние или конкретный commit;
  • создаёт новый каталог релиза;
  • запускает проверки до переключения;
  • меняет current атомарно;
  • сохраняет ограниченное число старых релизов;
  • удаляет только проверенные пути.

Не зашивайте в скрипт приватный ключ. Путь или имя учётной записи можно задавать окружением, но секретное значение остаётся вне Git.

Запишите рабочие команды в README

Минимальный README содержит следующие сведения. Это текстовый образец структуры документа, а не готовый набор команд для любого проекта:

Требования: поддерживаемые Node.js и npm
Установка: npm ci
Локальная работа: npm run dev
Проверка: npm run check
Сборка: npm run build
Публикация: npm run deploy
Откат: ./scripts/rollback.sh
Где находятся исходники, тесты и несекретные настройки

Команды должны совпадать с package.json и актуальными путями. Если для публикации требуется устное знание одного человека, структура ещё не решает задачу.

Проверьте проект перед первой фиксацией версии

В корне репозитория посмотрите состояние, отдельно прочитайте изменения lock-файла и только затем запустите предусмотренные проектом тесты и сборку:

git status --short
git diff -- . ':!package-lock.json'
git diff -- package-lock.json
npm test
npm run build

Отдельный просмотр lock-файла помогает заметить неожиданное массовое изменение. Перед git add проверьте также новые файлы: untracked секрет легко пропустить, если смотреть только обычный git diff.

Частые ошибки

  • Один каталог одновременно служит исходником и production root.
  • Собранный результат правят вручную.
  • .env.example содержит рабочее значение «для удобства».
  • В репозитории лежат backup-архивы.
  • package-lock.json регулярно удаляют и создают заново без причины.
  • Deploy-скрипт удаляет путь, сформированный из непроверенной переменной.
  • README описывает команды, которых уже нет.

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

Источники

Рекламное местоВаша компания здесьРазместить рекламу

Самопроверка

Проверьте, что материал усвоен

Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.

01Что должно находиться в .env.example?
02Какой файл помогает воспроизводить дерево npm-зависимостей?
03Что делать с каталогом, который полностью создаётся build-командой?

Разбираем коротко

Частые вопросы

Нужно ли коммитить каталог результата сборки в Git?

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

Можно ли хранить .env в приватном репозитории?

Не следует считать приватность репозитория достаточной защитой. Секреты расходятся по клонам, CI и резервным копиям; храните пример переменных без значений, а production-секреты передавайте отдельно.

Где хранить скрипты deploy и rollback?

В отдельном понятном каталоге репозитория, например scripts, чтобы они проходили review вместе с кодом. Сценарии не должны содержать реальные адреса доступа, токены и приватные ключи.