← Весь справочник

nginx

Устройство конфига nginx, выбор server и location, root против alias, proxy_pass, проверка и перезагрузка

nginx — веб-сервер и обратный прокси. Конфиг состоит из вложенных блоков-контекстов; для каждого запроса nginx выбирает один server и внутри него один location, и уже их директивы решают, что ответить: отдать файл, вернуть код или передать запрос дальше.

Синтаксис

nginx [опции]

Опции командной строки

ОпцияЧто делает
(без опций)запустить; мастер-процесс уходит в фон
-tпроверить конфиг и выйти: синтаксис, пути, сертификаты
-Tто же и напечатать весь собранный конфиг со всеми include
-s reloadперечитать конфиг без остановки: новые воркеры стартуют, старые дорабатывают запросы
-s quitплавно остановить — дождаться текущих запросов
-s stopостановить сразу
-s reopenпереоткрыть файлы логов (после ротации)
-c файлвзять другой главный конфиг
-g 'директивы;'добавить директивы верхнего уровня, например -g 'daemon off;' — не уходить в фон
-v / -Vверсия / версия, параметры сборки и модули
-qпри -t показывать только ошибки

Если nginx запущен как служба, то же самое делают systemctl reload nginx и systemctl restart nginx.

Структура конфига

Главный файл — /etc/nginx/nginx.conf. В Debian и Ubuntu он подключает conf.d/*.conf и sites-enabled/*; сайты кладут в sites-available/ и включают симлинком в sites-enabled/.

user www-data;                 # контекст main: процессы, логи
worker_processes auto;
events { worker_connections 768; }

http {                         # всё про HTTP
    include mime.types;
    access_log /var/log/nginx/access.log;

    upstream backend {         # группа серверов для proxy_pass
        server 127.0.0.1:9000;
    }

    server {                   # один сайт
        listen 8080;
        server_name example.local www.example.local;
        root /srv/site;
        index index.html;

        location / {           # правила для части URL
            try_files $uri $uri/ =404;
        }
        location /api/ {
            proxy_pass http://backend/;
        }
    }
}

Каждая директива заканчивается ;. Директивы внешнего блока (root, index, access_log) наследуются вложенными, если те их не переопределяют.

Как выбирается server

  1. По listen — адрес и порт, на которые пришло соединение.
  2. Среди них — по заголовку Host и server_name в таком порядке: точное имя → самый длинный шаблон со звёздочкой в начале (*.example.com) → со звёздочкой в конце (www.example.*) → первая подошедшая регулярка (~^…$).
  3. Ни одно не подошло — server с listen … default_server, а без него первый описанный для этого порта.

server_name _; — просто имя, которое ни с чем не совпадёт; «ловушкой для всего» такой сервер делает именно default_server.

Как выбирается location

ВидКак работает
location = /pathточное совпадение — выигрывает сразу
location ^~ /path/префикс; если он самый длинный из префиксов, регулярки не проверяются
location ~ regex / ~* regexрегулярка с учётом / без учёта регистра; первая подошедшая по порядку в файле
location /path/обычный префикс; запоминается самый длинный, но регулярки его перебивают

Порядок: точное совпадение → самый длинный префикс → если у него нет ^~, проверяются регулярки сверху вниз → если ни одна не подошла, остаётся самый длинный префикс.

Частые директивы

ДирективаЧто делает
listen 80; / listen 443 ssl;порт (и адрес: listen 127.0.0.1:8080;); default_server — сервер по умолчанию для порта
server_name a.com *.a.com;имена сайта
root /путь;каталог с файлами: путь к файлу = root + URI
alias /путь/;замена префикса location на путь (только внутри location)
index index.html;какой файл отдавать на запрос каталога
try_files $uri $uri/ /index.html;проверить файлы по очереди, последний вариант — запасной (URI или =404)
return 301 https://$host$request_uri;сразу ответить кодом; для 3xx — адрес перехода, для 2xx/4xx — текст
rewrite ^/old/(.*)$ /new/$1 permanent;переписать URI регуляркой; permanent — 301, redirect — 302, last — искать location заново
proxy_pass http://127.0.0.1:9000;передать запрос другому серверу или upstream
proxy_set_header Host $host;заголовок, который уйдёт на бэкенд
add_header X-Name value;добавить заголовок в ответ
allow 10.0.0.0/8; / deny all;доступ по IP; проверяются по порядку
auth_basic "текст"; + auth_basic_user_file файл;парольная защита (файл формата htpasswd)
error_page 404 /404.html;своя страница ошибки
autoindex on;показывать список файлов каталога
client_max_body_size 10m;максимальный размер тела запроса; больше — 413
access_log / error_logкуда писать логи; access_log off; — не писать
ssl_certificate / ssl_certificate_keyсертификат и ключ для listen … ssl
include файл;подключить другой файл (можно с шаблоном *)

Переменные

ПеременнаяЗначение
$uriпуть без параметров, после нормализации и rewrite
$request_uriисходный путь вместе с ?параметрами
$args / $arg_имястрока параметров / один параметр
$hostимя хоста из запроса
$remote_addrIP клиента
$schemehttp или https
$http_имялюбой заголовок запроса: $http_user_agent

root и alias, proxy_pass со слешем

КонфигЗапросКуда идёт
location /static/ { root /srv/site; }/static/a.cssфайл /srv/site/static/a.css — root + весь URI
location /files/ { alias /srv/files/; }/files/a.txtфайл /srv/files/a.txt — префикс заменён
location /api/ { proxy_pass http://backend/; }/api/usersна бэкенд уходит /users — префикс заменён на /
location /api/ { proxy_pass http://backend; }/api/usersна бэкенд уходит /api/users — URI без изменений

Логи

По умолчанию /var/log/nginx/access.log и /var/log/nginx/error.log. Строка access-лога (формат combined):

127.0.0.1 - admin [13/Oct/2026:15:24:29 +0000] "GET /pub/ HTTP/1.1" 200 412 "-" "curl/8.5.0"

IP клиента, пользователь Basic-авторизации, время, строка запроса, код ответа, размер тела, Referer, User-Agent. В error.log видно, какой файл nginx пытался открыть и почему не смог.

Примеры

# проверить синтаксис перед перезагрузкой — всегда
nginx -t && nginx -s reload

# какие listen и server_name реально попали в конфиг
nginx -T 2>/dev/null | grep -E '^\s*(listen|server_name)'

# включить сайт и применить
ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
nginx -t && nginx -s reload

# запустить на переднем плане — видно ошибки старта
nginx -g 'daemon off;'

# слушает ли nginx нужный порт
ss -tlnp | grep nginx

# проверить виртуальный хост, подставив заголовок Host
curl -s -H 'Host: example.local' http://localhost:8080/

# файл паролей для auth_basic
printf 'admin:%s\n' "$(openssl passwd -apr1 'secret')" > /etc/nginx/.htpasswd

# следить за запросами и ошибками
tail -f /var/log/nginx/access.log /var/log/nginx/error.log

# самые частые коды ответов
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

Подводные камни

  • Сначала nginx -t. nginx -s reload со сломанным конфигом не применяет его: старые процессы продолжают работать со старым конфигом, а ошибку легко не заметить. Проверка показывает файл и строку ошибки.
  • nginx -s reload работает, только если nginx запущен: иначе ошибка про /run/nginx.pid. Повторный nginx при запущенном даст bind() … Address already in use.
  • Регулярка перебивает обычный префикс. location /images/ проигрывает location ~ \.png$ для /images/a.png. Нужен приоритет префикса — пиши ^~.
  • Слеши в alias. location /files/ с alias /srv/files; (без слеша в конце) превратит /files/a.txt в /srv/filesa.txt. Слеш в конце ставь и в location, и в alias — или не ставь нигде.
  • root внутри location не обрезает путь. location /static/ { root /srv/site/static; } будет искать /srv/site/static/static/…. Это случай для alias.
  • Слеш в proxy_pass меняет URI, который увидит бэкенд (см. таблицу выше). Бэкенд отвечает 404 на правильный, казалось бы, путь — проверь этот слеш.
  • add_header в location отменяет все add_header уровнем выше, а не добавляется к ним. Заголовки, заданные в server, пропадут в таком location.
  • 404 и 403 объясняет error.log: там видно, какой именно путь на диске nginx пытался открыть и почему не смог (No such file or directory, Permission denied). Для 403 проверь права на каталоги по всему пути — пользователю www-data нужен x на каждом.
  • Нет ; — самая частая синтаксическая ошибка. Сообщение об ошибке указывает на строку после пропущенной точки с запятой.
  • location = /exact не совпадает с /exact/ — для точного совпадения важен каждый символ.

См. также

curl · ss · openssl · service · logrotate · chmod