Иерархия конфигурации Nginx от main и http до server, location и подключаемых файлов
DevOps

Структура конфигурации Nginx: контексты и include

Разбираем nginx.conf, контексты main, events, http, server и location, подключение include, команды nginx -t и -T, безопасное изменение и откат конфигурации.

Содержание

После установки Nginx настройки обычно распределены между nginx.conf и подключаемыми файлами отдельных сайтов. Поэтому изменение знакомой директивы может не подействовать: файл не подключён, правило находится не в том блоке или ниже действует более конкретная настройка.

Чтобы читать конфигурацию уверенно, нужно различать директивы и контексты, а затем найти их в полном дереве include. Команда nginx -T покажет это дерево, nginx -t проверит его перед применением, а reload перечитает успешную конфигурацию без полной остановки службы.

Директива и контекст

Директива задаёт один параметр Nginx. Простая директива заканчивается точкой с запятой; например, следующая строка выбирает число рабочих процессов автоматически:

worker_processes auto;

Блочная директива создаёт контекст и содержит вложенные настройки в фигурных скобках. Здесь HTTP-контекст включает один виртуальный сервер и правило для всех его путей:

http {
    server {
        listen 80;
        server_name example.com;

        location / {
            root /var/www/example;
        }
    }
}

Контекст определяет, какие директивы допустимы и кому они наследуются. Размещённые вне блоков директивы находятся в main-контексте. events и http обычно также находятся в main, server — в http, location — в server.

Документация каждой директивы перечисляет допустимые контексты. Если Nginx сообщает directive is not allowed here, проверьте не орфографию, а положение блока.

Как вложены основные контексты

Упрощённый nginx.conf ниже показывает только расположение уровней. Он не предназначен для замены конфигурации пакета: в реальном файле будут дополнительные настройки журналов, модулей и подключений:

user www-data;
worker_processes auto;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen 80;
        server_name example.com;
        root /var/www/example;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

Это упрощённая схема, а не готовая замена системного nginx.conf. Пакет дистрибутива добавляет журналирование, gzip, каталог виртуальных хостов и другие значения, поэтому сначала изучите существующее дерево include.

Найдите фактический путь и параметры сборки

nginx -V 2>&1

В выводе могут быть --conf-path, --prefix, пути модулей и временных каталогов. Не предполагайте, что любая установка использует /etc/nginx/nginx.conf.

Проверьте конфигурацию:

sudo nginx -t

Команда проверяет синтаксис и пытается открыть упомянутые файлы. Это важно: корректная строка с недоступным сертификатом или логом всё равно не должна применяться.

Разверните дерево include

sudo nginx -T

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

Ищите подключения:

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

Шаблон раскрывается при загрузке Nginx. Файл в sites-available сам по себе может не применяться, если на него нет ссылки из sites-enabled. В другом дистрибутиве такого деления может не быть вовсе.

Что наследуется, а что переопределяется

Поведение зависит от конкретной директивы. Нельзя считать, что все значения из http автоматически складываются с server и location. Некоторые наследуются только при отсутствии значения на вложенном уровне, другие объединяются по собственным правилам.

Всегда открывайте документацию нужного модуля. Например, изменение заголовков во вложенном location способно повлиять на наследование набора заголовков. Копирование фрагмента без понимания контекста создаёт скрытые различия между маршрутами.

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

Сделайте назначение файлов предсказуемым

Пакеты Debian и Ubuntu часто разделяют основной файл, общие фрагменты и сайты следующим образом. Это пример структуры каталогов, а не набор файлов, который требуется создать заново:

/etc/nginx/
├── nginx.conf
├── mime.types
├── conf.d/
├── sites-available/
└── sites-enabled/

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

Не подключайте резервные копии расширением, совпадающим с glob. Файл site.conf.backup обычно не соответствует *.conf, а site-old.conf — соответствует и может создать дубликат listen или server_name.

Безопасный цикл изменения

  1. Получите nginx -T и найдите исходный файл.
  2. Проверьте, что рабочее дерево конфигурации или backup актуальны.
  3. Измените один связанный фрагмент.
  4. Посмотрите diff.
  5. Выполните sudo nginx -t.
  6. Примените sudo systemctl reload nginx.
  7. Проверьте status, журнал и HTTP-ответ.

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

Диагностика типовых ошибок

unknown directive

Проверьте написание и наличие модуля через nginx -V. Директива из статьи для стороннего модуля не обязана поддерживаться вашей сборкой.

duplicate default server

Для одной пары адреса и порта объявлено несколько default_server. Найдите все совпадающие listen в nginx -T, а не только в текущем файле.

conflicting server name

Одно имя повторено на совпадающем listen. Nginx может проигнорировать конфликтующий фрагмент и вывести предупреждение. Уберите неоднозначность вместо игнорирования сообщения.

permission denied при nginx -t

Проверка пытается открыть сертификат, лог, include или другой ресурс. Проверьте точный путь и пользователя запуска, но не выдавайте широкие права всему каталогу.

Изменение не видно после reload

Убедитесь, что редактировали подключённый файл, тест был успешен, reload действительно выполнен, а запрос попадает на этот сервер. Сверьте PID и время журнала.

Откат

Верните ровно изменённый файл из проверенного Git commit или локальной копии. Затем:

sudo nginx -t
sudo systemctl reload nginx
systemctl status nginx --no-pager

Если новый nginx -t не прошёл, не делайте reload. Работающие процессы продолжают обслуживать прежнюю загруженную конфигурацию; сначала исправьте источник ошибки.

При настройке виртуальных хостов проверяйте, в каком контексте действует каждая директива. Если результат неожиданен, восстановите порядок прохождения HTTP-запроса по полной конфигурации nginx -T.

Первоисточники

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

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

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

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

01В каком контексте обычно располагаются server-блоки HTTP-сайтов?
02Как проверить все подключённые include-файлы перед применением?
03Почему нельзя редактировать только вывод nginx -T?

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

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

Где находится основной файл nginx.conf?

Путь зависит от способа установки и параметров сборки. Узнайте его через nginx -V и системную конфигурацию пакета, а фактически применяемое дерево безопаснее просматривать командой nginx -T.

Чем nginx -T отличается от nginx -t?

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

Нужно ли перезапускать Nginx после каждого изменения?

Нет. Сначала завершите связанное изменение, проверьте его через nginx -t, затем выполните reload. Полный restart обычно не нужен и создаёт лишний риск краткого прерывания обслуживания.