Практическая работа с Nginx: установка, настройка и эксплуатация

Курс научит устанавливать и настраивать Nginx для раздачи статики, работы как reverse proxy и балансировщика. Вы освоите базовые и продвинутые конфигурации, безопасность, TLS, логирование и диагностику проблем в реальной эксплуатации.

1. Введение в Nginx и архитектура веб-сервера

Введение в Nginx и архитектура веб-сервера

Зачем нужен Nginx

Nginx (произносится как engine-x) — это высокопроизводительный веб-сервер и прокси-сервер, который часто ставят «на вход» инфраструктуры, чтобы принимать HTTP(S)-запросы от клиентов и дальше:

  • отдавать статические файлы (HTML, CSS, JS, изображения);
  • проксировать запросы в приложение (например, Python/Node.js/Java/PHP);
  • балансировать нагрузку между несколькими бэкендами;
  • завершать TLS (HTTPS), чтобы шифрование было на Nginx, а внутри сети — обычный HTTP;
  • кэшировать ответы, снижая нагрузку на приложения.
  • Официальная документация: nginx: documentation. Общая справка: Nginx на Wikipedia.

    Базовые понятия: веб-сервер, клиент, HTTP

    Чтобы уверенно работать с Nginx, нужно одинаково понимать «кто с кем разговаривает».

  • Клиент — обычно браузер, мобильное приложение или другой сервер.
  • Веб-сервер — программа, которая принимает сетевые запросы и возвращает ответы.
  • HTTP — протокол, по которому клиент запрашивает ресурс (страницу, API-метод, файл), а сервер отвечает.
  • HTTPS — HTTP поверх шифрования TLS.
  • Важно различать два популярных типа контента:

  • Статический контент — файлы на диске, которые можно отдать «как есть».
  • Динамический контент — результат работы приложения (например, API или HTML, собранный на лету).
  • Какие роли может выполнять Nginx

    Один и тот же Nginx часто выполняет сразу несколько ролей.

    Веб-сервер для статики

    Nginx очень эффективен при раздаче файлов:

  • умеет быстро читать файлы с диска и отправлять клиентам;
  • поддерживает оптимизации вроде отправки больших файлов без лишнего копирования данных в памяти ОС.
  • Reverse proxy (обратный прокси)

    Reverse proxy — это сервер, который принимает запросы от клиента и пересылает их во внутренний сервис (бэкенд). Клиент при этом «думает», что общается с одним сервером.

    Зачем это нужно:

  • прятать внутреннюю сеть и реальные адреса сервисов;
  • централизованно настраивать HTTPS, логи, ограничения и заголовки;
  • разгружать приложение: статика и часть логики обрабатываются на уровне Nginx.
  • Load balancer (балансировщик)

    Если у вас несколько одинаковых бэкендов (реплик), Nginx может распределять запросы между ними.

    Типичные цели:

  • выдерживать больше нагрузки;
  • переживать падение одного узла;
  • раскатывать обновления безопаснее.
  • TLS termination (завершение HTTPS)

    Nginx принимает HTTPS от клиентов, расшифровывает трафик и дальше отправляет запросы внутрь как HTTP (или снова как HTTPS — по требованиям безопасности). Это упрощает конфигурацию приложений и позволяет:

  • централизованно управлять сертификатами;
  • применять единые настройки шифрования;
  • снижать нагрузку на бэкенды.
  • Как выглядит путь запроса в типичной схеме

    Ниже — распространённая архитектура: клиент приходит на Nginx, тот либо отдаёт статику, либо проксирует в приложение.

    !Диаграмма показывает, как Nginx стоит перед статикой и приложением и маршрутизирует запросы

    Практический смысл этой схемы:

  • снаружи у вас один вход (домен и порт), внутри — много сервисов;
  • Nginx становится точкой контроля: маршрутизация, безопасность, логирование.
  • Архитектура Nginx: почему он быстрый

    Событийная модель и неблокирующий ввод-вывод

    Nginx построен вокруг событийной модели (event-driven). Идея простая:

  • один рабочий процесс (worker) может обслуживать множество соединений;
  • вместо «зависания» на одном соединении Nginx ждёт событий от ОС (например, «готово к чтению» или «готово к записи») и переключается между задачами.
  • Это особенно выгодно, когда одновременно подключено много клиентов, и часть времени соединения простаивают (ожидание сети, ожидание клиента и т.д.).

    Master и worker процессы

    Обычно Nginx запускается как набор процессов:

  • master process — главный процесс, читает конфигурацию и управляет рабочими;
  • worker processes — выполняют реальную работу: принимают соединения, обрабатывают запросы, отдают ответы.
  • Ключевой практический момент: многие изменения можно применять без остановки сервиса.

    «Мягкая» перезагрузка конфигурации

    Nginx умеет перечитывать конфигурацию и поднимать новые worker-процессы, постепенно завершая старые. Это полезно, потому что:

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

    Что такое конфигурация Nginx (самая важная идея)

    Nginx настраивается через файл(ы) конфигурации, состоящие из директив.

  • Директива — инструкция вида имя значение;.
  • Контекст — блок директив в фигурных скобках, задающий область применения.
  • Чаще всего в HTTP-сценариях встречаются контексты:

  • http — общие настройки HTTP-сервера;
  • server — виртуальный сервер (обычно соответствует домену/порту);
  • location — правила обработки конкретных путей URL.
  • Важная мысль для старта: маршрутизация и поведение Nginx описываются не «кодом», а правилами в этих контекстах.

    Где Nginx находится в реальной эксплуатации

    В продакшене Nginx обычно связан с тремя слоями:

  • Сеть и DNS: доменное имя указывает на сервер/балансировщик, где стоит Nginx.
  • Безопасность: TLS, ограничения, базовая фильтрация, иногда WAF-решения.
  • Приложения: сервисы за Nginx получают уже нормализованный поток запросов.
  • Типовые эксплуатационные вопросы, которые будут центральными в этом курсе:

  • как установить Nginx и выбрать источник пакетов;
  • как устроены файлы конфигурации и как не запутаться в include;
  • как сделать reverse proxy к приложению и правильно прокинуть заголовки;
  • как включить HTTPS и обновлять сертификаты;
  • как читать логи и диагностировать ошибки;
  • как делать безопасные изменения без простоя.
  • Итоги

  • Nginx — это веб-сервер и одновременно мощный reverse proxy.
  • Он часто стоит «на входе» и решает задачи статики, проксирования, балансировки и TLS.
  • Высокая производительность достигается за счёт событийной модели и разделения на master/worker.
  • Конфигурация — это набор директив в контекстах http, server, location, которыми вы управляете маршрутизацией и поведением сервера.
  • 2. Установка и базовая конфигурация Nginx

    Установка и базовая конфигурация Nginx

    Связь с предыдущей темой

    В прошлой статье мы разобрали, что Nginx часто стоит на входе инфраструктуры и управляется через конфигурацию из контекстов http, server, location. Теперь перейдём к практике: установим Nginx, разберёмся, где лежат файлы конфигурации, как безопасно проверять изменения и сделаем минимальную рабочую конфигурацию для статики и reverse proxy.

    Установка Nginx

    Выбор источника установки

    Обычно есть два варианта:

  • Пакеты из репозитория вашей ОС: проще и стабильнее, но версия может быть не самой свежей.
  • Официальный репозиторий Nginx: чаще даёт более новые версии и некоторые сборочные варианты.
  • Полезные ссылки:

  • Официальная документация Nginx
  • Инструкция по установке из официального репозитория
  • Установка на Debian и Ubuntu

  • Обновите индекс пакетов:
  • Установите Nginx:
  • Проверьте, что сервис запущен:
  • Проверьте, что Nginx отвечает по сети:
  • Если всё хорошо, вы увидите строку статуса вроде HTTP/1.1 200 OK или HTTP/1.1 304 Not Modified.

    Установка на RHEL, Rocky Linux, AlmaLinux, CentOS

  • Установите Nginx из репозитория дистрибутива:
  • Включите автозапуск и запустите сервис:
  • Проверьте статус:
  • Установка на Alpine Linux

  • Установка пакета:
  • Запуск и добавление в автозагрузку зависит от init-системы, чаще всего OpenRC:
  • Где лежит конфигурация и как она устроена

    Главный файл и включаемые фрагменты

    Обычно основной файл конфигурации:

  • /etc/nginx/nginx.conf
  • Внутри него часто используются директивы include, которые подключают дополнительные файлы. Из-за этого фактическая конфигурация обычно разнесена по нескольким файлам.

    Частые варианты структуры (зависят от ОС и сборки):

  • Debian/Ubuntu: /etc/nginx/sites-available/ и /etc/nginx/sites-enabled/
  • Универсально: /etc/nginx/conf.d/*.conf
  • !Визуально показывает, как nginx.conf подключает дополнительные конфиги через include

    Как посмотреть «итоговую» конфигурацию

    В эксплуатации важно уметь понять, что реально применит Nginx после всех include.

  • Показать активную конфигурацию целиком (с учётом include):
  • Найти, где определён конкретный server_name или порт:
  • Управление сервисом и безопасное применение изменений

    Базовые команды systemd

  • Запустить:
  • Остановить:
  • Перезапустить (полная перезагрузка процесса):
  • Перечитать конфигурацию без полного рестарта:
  • Перезагрузка (reload) обычно предпочтительнее в продакшене, потому что Nginx может аккуратно применить новый конфиг и не «уронить» активные соединения резким остановом процесса.

    Проверка конфигурации перед применением

    Главная привычка, которая экономит время и снижает риски: всегда проверяйте конфиг перед reload.

  • Проверить синтаксис и базовую корректность:
  • Типичный безопасный цикл изменений:
  • Отредактировали файл.
  • Выполнили sudo nginx -t.
  • Если ошибок нет, выполнили sudo systemctl reload nginx.
  • Минимальная конфигурация: один сайт со статикой

    Понятные термины перед началом

  • Виртуальный хост в Nginx — это блок server, который описывает, как отвечать на запросы для конкретного домена и порта.
  • Корень сайта — папка на диске, из которой Nginx отдаёт файлы; задаётся директивой root.
  • Путь запроса — часть URL после домена, например /images/logo.png; обрабатывается правилами location.
  • Пример server-блока

    Ниже пример, который слушает порт 80 и отдаёт файлы из /var/www/example.

    Что здесь происходит:

  • listen 80; означает, что Nginx принимает HTTP-запросы на порту 80.
  • server_name example.local; задаёт доменное имя, для которого подходит этот блок.
  • root /var/www/example; задаёт папку, где лежат файлы сайта.
  • index index.html; говорит, какой файл считать главным, если запрошена директория.
  • location / { ... } задаёт правило для всех путей, начинающихся с /.
  • try_files uri/ =404; пытается найти файл на диске и, если не нашёл, возвращает 404.
  • Куда положить этот server-блок

    Вариант зависит от вашей системы.

  • Debian/Ubuntu (распространённый подход с sites-available):
  • Создайте файл:
  • Вставьте туда server { ... }.
  • Включите сайт символической ссылкой:
  • Проверьте и примените:
  • Универсальный вариант через conf.d:
  • Создайте файл:
  • Вставьте server { ... }.
  • Проверьте и примените конфигурацию.
  • Подготовка файлов сайта и проверка

  • Создайте папку и тестовую страницу:
  • Проверьте ответ:
  • Если вы используете server_name example.local, а проверяете с локальной машины, может понадобиться подставить Host-заголовок:

    Базовый reverse proxy к приложению

    Зачем это нужно

    Если ваше приложение работает на другом порту (например, 127.0.0.1:3000), Nginx может принять запросы снаружи и передать их в приложение. Это и есть reverse proxy.

    Минимальный пример проксирования

    Предположим, приложение слушает http://127.0.0.1:3000.

    Что важно в этих заголовках:

  • Host помогает приложению понимать, на какой домен пришли.
  • X-Real-IP и X-Forwarded-For передают реальный IP клиента (иначе приложение увидит IP самого Nginx).
  • X-Forwarded-Proto передаёт схему http или https (понадобится, когда включите TLS).
  • Логи и диагностика на базовом уровне

    Какие логи бывают

  • Access log — журнал запросов: кто, куда, с каким статусом.
  • Error log — ошибки Nginx: проблемы конфигурации, доступа к файлам, соединения с бэкендом.
  • Частые расположения логов:

  • /var/log/nginx/access.log
  • /var/log/nginx/error.log
  • Как быстро посмотреть, что происходит

  • Смотреть ошибки в реальном времени:
  • Посмотреть последние запросы:
  • Типовые проблемы и как их распознать

  • nginx -t ругается на синтаксис: Nginx не применит конфиг, пока вы не исправите ошибку.
  • 403 Forbidden при раздаче статики: часто проблема в правах доступа к каталогу или файлу.
  • 502 Bad Gateway при proxy_pass: Nginx не смог подключиться к приложению (не запущено, не тот порт, firewall, неправильный адрес).
  • Итоги

  • Установить Nginx проще всего из пакетов ОС, но официальный репозиторий полезен для более новых версий.
  • Основной конфиг обычно в /etc/nginx/nginx.conf , а реальные server-блоки часто лежат в подключаемых файлах.
  • Перед применением изменений используйте nginx -t, а затем systemctl reload nginx.
  • Минимальная конфигурация сводится к server и location, где вы либо отдаёте статику через root, либо проксируете запросы через proxy_pass.
  • Логи access.log и error.log — первые места, куда стоит смотреть при проблемах.
  • 3. Статика, server blocks и маршрутизация запросов

    Статика, server blocks и маршрутизация запросов

    Связь с предыдущими темами

    В прошлых статьях мы установили Nginx, нашли файлы конфигурации и сделали минимальные примеры для статики и reverse proxy. Теперь углубимся в самое практическое: как Nginx выбирает нужный server (виртуальный хост), как внутри него выбирается нужный location, и как на этом строится корректная раздача статики и маршрутизация запросов.

    Ключевая идея: почти все «магические» эффекты Nginx (почему один запрос попал в один конфиг, а другой в другой) объясняются двумя этапами выбора:

  • Выбор server по listen и server_name.
  • Выбор location по правилам совпадения пути.
  • !Показано, как Nginx последовательно выбирает server и location и что происходит дальше

    Термины, которые понадобятся

  • Виртуальный хост — блок server { ... }, описывает поведение для конкретного порта и имени сайта.
  • URI — путь в запросе без домена, например /assets/app.css.
  • Host — домен из HTTP-заголовка Host (обычно соответствует server_name).
  • Контекст — область, где разрешены директивы (например, http, server, location).
  • Статика — файлы на диске, которые Nginx отдаёт напрямую.
  • Как Nginx выбирает server block

    Роль listen

    listen определяет, на каком порту (и иногда на каком IP-адресе) Nginx принимает соединения.

    Примеры:

    Это два разных виртуальных хоста: один отвечает на порту 80, другой на 8080.

    Роль server_name и заголовка Host

    После того как запрос попал на нужный порт, Nginx выбирает server на основе Host.

  • Если Host: app.local, Nginx будет искать server { server_name app.local; }.
  • Если совпадений несколько, применяются правила приоритета (специфичность, шаблоны и т.д.).
  • Подробно: документация директивы server_name в модуле ngx_http_core_module: Документация server_name

    Что такое default_server

    Если Nginx не нашёл подходящий server_name, он использует сервер по умолчанию для этого listen.

    Практический смысл:

  • удобно «поймать» неожиданные домены и не отдавать им ваш сайт;
  • помогает диагностировать, когда запросы приходят не с тем Host.
  • Подробнее о listen: Документация listen

    Как проверить выбор server на практике

    Если вы тестируете на 127.0.0.1, обязательно задавайте Host, иначе вы можете попасть в default_server.

    Как Nginx выбирает location внутри server

    Когда server выбран, Nginx выбирает обработчик по URI через location.

    Директива location и правила совпадения: Документация location

    Виды location и их смысл

    Есть несколько основных типов:

  • Точное совпадение: location = /health { ... }
  • Префиксное совпадение (самый частый случай): location /api/ { ... }
  • Префикс с запретом regex-поиска: location ^~ /static/ { ... }
  • Регулярное выражение (чувствительно к регистру): location ~ \.png { ... }
  • Упрощённые правила приоритета

    Чтобы уверенно читать конфиги, держите в голове практическую последовательность:

  • location = ... (точное совпадение) имеет максимальный приоритет.
  • Среди префиксных location /... выбирается самый длинный подходящий префикс.
  • Если выбранный префикс был с ^~, на этом выбор заканчивается (regex не проверяются).
  • Иначе Nginx проверяет regex-локации (~ и ~*) и при первом совпадении берёт его.
  • Если regex не совпали, остаётся выбранный префикс.
  • !Пошаговая логика выбора location

    Пример: API, статика и главная страница

    Что произойдёт:

  • /health попадёт в точный location = /health.
  • /api/users попадёт в location /api/.
  • /css/site.css попадёт в location / и будет искаться на диске.
  • Раздача статики: root, alias, index, try_files

    Директива root

    root задаёт базовую директорию, к которой Nginx добавляет URI.

    Пример:

    Запрос:

  • URI: /static/app.js
  • путь на диске: /var/www/site/static/app.js
  • Документация: Документация root

    Директива alias

    alias заменяет совпавшую часть пути на указанную директорию. Это удобно, когда URI не должен повторяться на диске.

    Запрос:

  • URI: /static/app.js
  • путь на диске: /var/www/assets/app.js
  • Документация: Документация alias

    root и alias: практическая разница

    | Задача | Правильнее выбрать | Почему | |---|---|---| | Каталог на диске повторяет URI (/static/... лежит в .../static/...) | root | проще и меньше сюрпризов | | URI /static/..., а на диске файлы лежат без /static | alias | не нужно создавать лишний подкаталог |

    Частая ошибка: использовать root там, где нужен alias, и получить лишний сегмент пути (например, поиск /var/www/assets/static/app.js вместо /var/www/assets/app.js).

    index

    index задаёт список файлов, которые Nginx попробует отдать, если запрошена директория.

    Если клиент запросит /, Nginx попробует /var/www/example/index.html, затем /var/www/example/index.htm.

    Документация: Документация index

    try_files: главный инструмент безопасной статики

    try_files последовательно проверяет наличие файлов и выбирает первый найденный вариант.

    Самый частый шаблон для статики:

    Смысл:

  • uri/ — попробовать директорию (и тогда сработает index);
  • =404 — если ничего нет, вернуть 404, а не отдавать что-то «по умолчанию».
  • Документация: Документация try_files

    SPA-случай: отдавать index.html для «виртуальных» роутов

    Для одностраничных приложений (SPA) часто нужно: если файл не найден, отдать index.html, чтобы роутинг сделал фронтенд.

    Практическая проверка: /assets/app.js будет файлом, а /profile/settings (не файл) перейдёт на /index.html.

    Маршрутизация: типовые схемы в одном server

    Статика отдельно, приложение отдельно

    Практический смысл:

  • проще изолировать конфиги и корни сайтов;
  • понятнее диагностика: ошибки и логи легче сопоставить с доменом.
  • Частые ошибки и как их быстро диагностировать

    Вы попали не в тот server

    Признаки:

  • отдаётся «дефолтная» страница Nginx;
  • ваш location как будто «не работает».
  • Что сделать:

  • Посмотрите, какой Host реально уходит:
  • Повторите с правильным Host:
  • Выведите активную конфигурацию и проверьте порядок и listen:
  • 404, хотя файл существует

    Частые причины:

  • неправильный root или alias;
  • проблема с правами доступа к каталогу;
  • вы ожидаете /static/app.js, а Nginx ищет /.../static/static/app.js из-за неверного выбора между root и alias.
  • Смотрите error.log:

    location отрабатывает не так, как вы думали

    Причины:

  • сработал regex location ~ ..., потому что префикс был без ^~;
  • точный location = ... перехватил запрос.
  • Лучший способ понять реальность:

  • временно добавьте разные return 200 "..."; в спорные location и посмотрите, что отвечает;
  • убедитесь, что после правок вы сделали nginx -t и reload.
  • Итоги

  • Сначала Nginx выбирает server по listen и server_name, и только потом location по URI.
  • default_server помогает безопасно обрабатывать «чужие» домены и быстрее диагностировать ошибки Host.
  • Понимание приоритета location (точное, префиксы, ^~, regex) — основа предсказуемой маршрутизации.
  • Для статики чаще всего нужны root или alias вместе с try_files, а index управляет тем, что отдавать для директорий.
  • Большинство проблем решается проверкой Host, чтением nginx -T и просмотром error.log.
  • 4. Reverse proxy, upstream и балансировка нагрузки

    Reverse proxy, upstream и балансировка нагрузки

    Связь с предыдущими темами

    В предыдущих статьях вы настроили server-блоки, поняли, как Nginx выбирает нужный server и location, и сделали базовый proxy_pass на один бэкенд. Теперь сделаем следующий практический шаг: научимся проксировать запросы в пул бэкендов, управлять балансировкой и отказоустойчивостью, и диагностировать проблемы на стыке Nginx и приложения.

    !Как Nginx распределяет запросы по бэкендам через upstream

    Что такое reverse proxy в практическом смысле

    Reverse proxy — это режим, когда Nginx принимает запрос от клиента и пересылает его во внутренний сервис.

    Практические причины, почему reverse proxy используют почти всегда:

  • единая точка входа для HTTP и HTTPS;
  • единое логирование и метрики на входе;
  • изоляция внутренней сети и портов приложений;
  • возможность балансировать нагрузку между несколькими экземплярами приложения.
  • Документация по проксированию: Модуль ngx_http_proxy_module.

    proxy_pass: базовая директива и самая частая ловушка

    proxy_pass задаёт, куда Nginx должен отправить запрос.

    Простейший вариант (один бэкенд):

    Документация: Директива proxy_pass.

    Важная разница: proxy_pass со слешем и без

    Поведение зависит от того, есть ли завершающий / в proxy_pass.

    Сравните два варианта для location /api/.

    Вариант без завершающего слеша:

    Смысл: Nginx передаст URI как есть (например, /api/users).

    Вариант с завершающим слешем:

    Смысл: Nginx заменит совпавшую часть URI (/api/) на / (например, /users).

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

  • если ваше приложение ожидает маршруты с префиксом /api, используйте proxy_pass без завершающего /;
  • если ваше приложение ожидает маршруты без /api, используйте proxy_pass с завершающим /.
  • Какие заголовки обычно нужно прокидывать в приложение

    По умолчанию приложение будет видеть соединение от Nginx, а не от реального клиента. Поэтому обычно прокидывают как минимум:

    Документация: Директива proxy_set_header.

    Практический смысл каждого заголовка:

  • Host помогает приложению корректно обрабатывать мультидоменные сценарии и генерацию ссылок;
  • X-Real-IP передаёт приложению IP клиента;
  • X-Forwarded-For добавляет IP клиента в цепочку прокси;
  • X-Forwarded-Proto помогает приложению понять, был ли внешний запрос по http или https.
  • Если у вас WebSocket или SSE

    Для WebSocket часто нужны HTTP/1.1 и корректные заголовки апгрейда:

    Если вам нужна консистентность при добавлении/удалении бэкендов, обратите внимание на параметры hash в документации модуля upstream.

    Отказоустойчивость: что происходит, когда бэкенд «падает»

    В реальности бэкенд может быть недоступен из-за перезапуска, деплоя или сетевой проблемы. Задача Nginx — быстро переключиться на другой бэкенд и не «ронять» клиентские запросы.

    Пассивное исключение бэкендов

    В upstream можно указать, когда считать бэкенд проблемным:

    Практический смысл:

  • max_fails=3 означает: если подряд произошло несколько неудачных попыток (ошибка соединения, таймаут), бэкенд помечается как «нежелательный»;
  • fail_timeout=10s задаёт окно времени, в котором учитываются ошибки, и период, на который бэкенд временно исключается из ротации.
  • Это пассивный механизм: Nginx не ходит «пинговать» бэкенды отдельно, а делает выводы по реальным запросам.

    Повтор запроса на другой бэкенд: proxy_next_upstream

    При некоторых ошибках Nginx может повторить запрос на другой upstream-сервер.

    Документация: Директива proxy_next_upstream.

    Важный практический момент:

  • повтор запроса может быть опасен для неидемпотентных операций (например, POST на создание заказа), если приложение не защищено от дублей;
  • чаще всего безопаснее ретраить только идемпотентные запросы или использовать идемпотентные ключи на стороне приложения.
  • Производительность: keepalive-соединения к upstream

    Если Nginx каждый раз устанавливает новое TCP-соединение к бэкенду, это лишние задержки и нагрузка. Для высоконагруженных систем обычно включают keepalive к upstream.

    Пример:

    Документация: Директива keepalive в upstream.

    Диагностика: как увидеть, куда реально ушёл запрос

    Когда появляется балансировка, в логах важно видеть, какой upstream обслужил запрос и сколько времени заняли разные этапы.

    Пример удобного формата логов:

    Практический смысл переменных:

  • upstream_status показывает статус, который вернул бэкенд;
  • upstream_response_time помогает понять, тормозит ли приложение.
  • Переменные, связанные с upstream, описаны в документации Nginx: Модуль ngx_http_upstream_module.

    Практический пример: статика напрямую, API через upstream-пул

    Сценарий:

  • фронтенд-статика лежит на диске;
  • API обслуживается двумя репликами приложения;
  • для неизвестных доменов есть default_server, чтобы не «светить» конфиг.
  • Что здесь важно заметить:

  • location ^~ /assets/ гарантирует предсказуемую обработку статики;
  • /api/ уходит в upstream, где включён least_conn и пассивное исключение плохих бэкендов;
  • try_files ... /index.html даёт корректную работу SPA-роутинга для фронтенда.
  • Итоги

  • proxy_pass превращает Nginx в reverse proxy, а upstream позволяет описать пул бэкендов.
  • Поведение URI при proxy_pass зависит от завершающего /, и это частый источник ошибок.
  • Балансировка может быть простой (round-robin) или более управляемой (least_conn, ip_hash, hash).
  • Отказоустойчивость обычно строится на пассивном исключении бэкендов и аккуратных ретраях через proxy_next_upstream.
  • Для эксплуатации критично логировать upstream-поля, чтобы быстро видеть, какой бэкенд отвечает и где возникают задержки.
  • 5. HTTPS, TLS и безопасность конфигурации

    HTTPS, TLS и безопасность конфигурации

    Связь с предыдущими темами

    Ранее вы настроили server-блоки, правила location, научились отдавать статику и проксировать запросы в приложение (в том числе через upstream). Теперь добавим обязательный для продакшена слой: HTTPS.

    На практике это означает, что Nginx будет:

  • принимать зашифрованные соединения на 443;
  • предъявлять клиенту сертификат;
  • расшифровывать трафик и дальше либо отдавать статику, либо проксировать запросы в приложение;
  • применять дополнительные меры безопасности конфигурации, чтобы снизить риски.
  • !Понимание, где заканчивается TLS и где начинается обычный HTTP

    Что такое HTTPS и что такое TLS

  • HTTPS — это HTTP поверх шифрования.
  • TLS — криптографический протокол, который обеспечивает:
  • шифрование трафика;
  • целостность (защита от незаметной подмены данных);
  • аутентификацию сервера (клиент проверяет, что домен действительно обслуживает тот, кто предъявил сертификат).
  • В терминах Nginx: HTTPS включается в server { ... }, где вы добавляете listen 443 ssl; и указываете сертификат и приватный ключ.

    Сертификат, ключ и цепочка доверия

    Чтобы клиент доверял вашему сайту, ему нужно проверить сертификат.

    Основные элементы

  • Приватный ключ — секретный файл на сервере. Он доказывает, что вы владеете сертификатом.
  • Сертификат — публичный файл, который Nginx отдаёт клиенту. В сертификате указаны домены (например, example.com и www.example.com).
  • Цепочка сертификатов — дополнительные сертификаты (обычно промежуточные), которые помогают клиенту связать ваш сертификат с доверенным центром сертификации.
  • Практическое правило: приватный ключ должен быть доступен только root и пользователю, под которым Nginx читает ключ, и не должен попадать в репозитории.

    !Визуально объясняет, почему нужен fullchain и как работает доверие

    Где взять сертификат

    Основные варианты:

  • сертификат от публичного CA (чаще всего Let’s Encrypt);
  • корпоративный CA (внутренние инфраструктуры);
  • самоподписанный сертификат (подходит для тестов, но браузер будет предупреждать).
  • Рекомендованный вариант для продакшена: Let’s Encrypt.

    Ссылки:

  • Let's Encrypt
  • Certbot
  • Как Nginx выбирает правильный сертификат

    Когда на одном IP обслуживаются несколько доменов, клиент при установлении TLS-соединения сообщает имя сайта через расширение SNI.

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

  • в Nginx вы создаёте отдельные server-блоки на listen 443 ssl; с разными server_name и сертификатами;
  • нужен также default_server на 443, чтобы корректно обработать неожиданные домены.
  • Включаем HTTPS в Nginx: минимальный рабочий пример

    Ниже — минимальная конфигурация для домена example.com.

    Что важно:

  • ssl_certificate обычно указывает на fullchain.pem, чтобы клиент получил цепочку.
  • ssl_certificate_key указывает на приватный ключ.
  • Проверка и применение:

    Редирект с HTTP на HTTPS и ACME-челлендж

    Зачем нужен редирект

    Чтобы пользователи всегда работали по HTTPS, обычно делают отдельный server на 80, который возвращает редирект.

    Важный нюанс для Let’s Encrypt

    Если вы получаете сертификат через HTTP-валидацию (http-01), CA должен суметь сходить по пути /.well-known/acme-challenge/... по HTTP.

    Частый практический подход: разрешить этот путь на 80, а всё остальное редиректить.

    Получение сертификата Let’s Encrypt через Certbot (пример для Ubuntu/Debian)

    На практике удобнее всего использовать Certbot, который:

  • получает сертификаты;
  • настраивает автопродление;
  • может автоматически обновлять конфигурацию Nginx.
  • Пример установки (вариант через snap часто рекомендован самим Certbot):

    Получение сертификата с автоматической настройкой Nginx:

    Проверка таймера продления:

    Ссылки:

  • Инструкции Certbot для Nginx
  • Рекомендованные настройки TLS: протоколы, шифры, сессии

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

    Практически безопасный подход:

  • включить современные версии протокола;
  • не включать устаревшие и небезопасные варианты;
  • включить HTTP/2 (если вам нужно) для ускорения загрузки на HTTPS.
  • Хороший источник для генерации конфигурации: Mozilla SSL Configuration Generator.

    Пример набора директив, который часто используют как отдельный подключаемый файл (проверьте актуальность в вашем окружении):

    Комментарии по смыслу:

  • ssl_protocols ограничивает версии TLS.
  • ssl_session_cache и ssl_session_timeout помогают повторным подключениям быть быстрее.
  • http2listen) включает HTTP/2 на TLS-соединении.
  • HSTS и безопасные HTTP-заголовки

    TLS шифрует соединение, но полезно добавить защитные заголовки, которые помогают браузеру безопаснее интерпретировать контент.

    HSTS

    HSTS говорит браузеру: в следующий раз ходи на этот домен только по HTTPS.

    Практические предостережения:

  • включайте HSTS только после того, как вы уверены, что HTTPS работает стабильно;
  • более строгий вариант с includeSubDomains может затронуть поддомены;
  • параметр preload требует отдельного процесса добавления домена в списки браузеров.
  • Документация: Директива add_header

    Базовый набор защитных заголовков

    Один из практичных стартовых наборов:

    Что это даёт:

  • X-Content-Type-Options снижает риск опасного автоопределения типов.
  • X-Frame-Options защищает от встраивания сайта в iframe (кликджекинг) в простых сценариях.
  • Referrer-Policy уменьшает утечки URL через Referer.
  • Про Content Security Policy (CSP): это мощный заголовок, но его лучше вводить отдельно и аккуратно, потому что он часто ломает фронтенд при неправильной политике.

    Безопасность конфигурации Nginx: практический чеклист

    Закрыть неожиданные домены: default_server

    Как и для 80, полезно иметь default_server и на 443, чтобы запросы с чужими Host не попадали в «случайный» виртуальный хост.

    444 — специальный код Nginx: соединение закрывается без ответа.

    Спрятать версию Nginx

    Документация: Директива server_tokens

    Защитить приватный ключ и файлы сертификатов

    Типовые рекомендации:

  • права на приватный ключ: 600 (владелец root);
  • каталог с ключами не должен быть доступен на чтение другим пользователям;
  • приватный ключ не должен попадать в root сайта.
  • Проверить права:

    Не отдавать лишнее из файловой системы

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

    Пример запрета для файлов, начинающихся с точки:

    Пояснение:

  • регулярное выражение ловит /.git, /.env и подобное;
  • исключение для /.well-known оставляет возможность ACME-валидации.
  • Ограничить размеры и таймауты (как минимум на старте)

    Это не «панацея», но уменьшает риск тривиальных злоупотреблений.

    Примеры:

    Документация:

  • Директива client_max_body_size
  • Проверка HTTPS и диагностика

    Быстрая проверка через curl

    Проверить, что сайт отвечает по HTTPS:

    Проверить редирект с HTTP на HTTPS:

    Проверка сертификата и SNI через openssl

    На что смотреть:

  • что отдается правильный сертификат для нужного домена;
  • есть ли ошибки в цепочке;
  • какая версия TLS и набор шифров согласовались.
  • Где искать причины ошибок

  • синтаксические ошибки: sudo nginx -t;
  • ошибки загрузки ключа и сертификата: sudo tail -n 200 /var/log/nginx/error.log;
  • ошибки доступа к файлам (права, SELinux) часто проявляются как проблемы чтения ssl_certificate_key.
  • Документация по логам: Модуль логирования Nginx

    Итоги

  • HTTPS в Nginx включается через listen 443 ssl; и указание ssl_certificate и ssl_certificate_key.
  • Для продакшена удобнее и безопаснее получать сертификаты через Let’s Encrypt и Certbot.
  • Важно понимать SNI, если на одном сервере несколько доменов.
  • Безопасная эксплуатация — это не только TLS, но и default_server, server_tokens off, защита скрытых файлов, аккуратные лимиты и корректные права на ключ.
  • Диагностика HTTPS обычно сводится к nginx -t, error.log, curl и openssl s_client.
  • 6. Логи, мониторинг, диагностика и отладка

    Логи, мониторинг, диагностика и отладка

    Связь с предыдущими темами

    Ранее вы настроили server-блоки и location, раздачу статики, reverse proxy, upstream и HTTPS. На практике после первой же «боевой» настройки возникает следующий вопрос: как быстро понять, что именно сломалось и где?

    Ответ почти всегда начинается с трёх опорных точек:

  • Логи Nginx: что происходило на входе и что пошло не так.
  • Мониторинг: какие тенденции по соединениям, ошибкам и задержкам.
  • Диагностика и отладка: как локализовать проблему до конкретного server/location, файла или upstream.
  • !Карта «куда смотреть» при проблемах со статикой и прокси

    Какие логи есть в Nginx и зачем

    В HTTP-сценариях ключевые логи два:

  • Access log: журнал всех обработанных HTTP-запросов (кто пришёл, что запросил, какой статус, сколько заняло времени).
  • Error log: журнал ошибок и предупреждений внутри Nginx (ошибка чтения файла, проблемы подключения к upstream, ошибки TLS и т.д.).
  • Документация:

  • nginx: ngx_http_log_module
  • nginx: error_log
  • Access log: как сделать его полезным для эксплуатации

    Где обычно лежит

    Часто по умолчанию:

  • /var/log/nginx/access.log
  • /var/log/nginx/error.log
  • Но важнее не путь, а то, что access log можно задавать на разных уровнях:

  • в контексте http (по умолчанию для всех виртуальных хостов);
  • в server (раздельно по сайтам);
  • в location (точечно для «шумных» или критичных ручек).
  • Как устроен формат логов

    Access log пишется по шаблону log_format, а включается директивой access_log.

    Пример «минимально полезного» формата (видно домен, запрос, статус, размер, реферер, user-agent и тайминги):

    nginx error_log /var/log/nginx/error.log warn; bash nginx -V ``

    Документация по отладке: nginx: debugging log

    Как быстро понять проблему по error log

    Типовые ситуации:

  • Статика
  • - permission denied означает проблемы прав на файл или каталог. - open() "..." failed (2: No such file or directory) означает неверный root/alias или отсутствие файла.
  • Reverse proxy
  • -
    connect() failed (111: Connection refused) while connecting to upstream означает, что на upstream-порту никто не слушает. - upstream timed out (110: Connection timed out) означает, что бэкенд не ответил вовремя.
  • TLS
  • - ошибки чтения
    ssl_certificate_key часто означают права/SELinux или неверный путь.

    Типовые HTTP-коды в эксплуатации и что они обычно означают

    Таблица как «шпаргалка» для первичной диагностики:

    | Код | Где возникает | Частый смысл | Где смотреть дальше | |---|---|---|---| | 404 | Nginx (статика) или приложение | файл не найден или маршрут не существует | error.log (для статики), логи приложения (для API) | | 403 | чаще Nginx (статика) | нет прав на файл/каталог, запрет location | error.log с permission denied | | 400 | Nginx | некорректный запрос, слишком большие заголовки и т.п. | error.log, лимиты client_* | | 499 | Nginx | клиент закрыл соединение до ответа | access log с 9 ~ /^5/ {print upstream_addr, upstream_response_time.

  • Базовый мониторинг можно начать со stub_status, а затем подключить Prometheus через экспортер.
  • Самый практичный навык эксплуатации это повторяемый алгоритм: nginx -t и nginx -T` → access log → error log → проверка статики или upstream.
  • 7. Оптимизация производительности и эксплуатация в продакшене

    Оптимизация производительности и эксплуатация в продакшене

    Связь с предыдущими темами

    Ранее вы научились строить маршрутизацию через server и location, отдавать статику, проксировать в приложение через proxy_pass и upstream, включать HTTPS и разбираться с логами и диагностикой. Теперь соберём это в практику продакшен-эксплуатации: как сделать конфигурацию предсказуемой под нагрузкой, сократить задержки, выдерживать пиковые соединения и безопасно выкатывать изменения.

    !Карта того, какие оптимизации применяются на каких этапах обработки запроса

    Как думать о производительности Nginx

    Производительность на входе обычно упирается в три ресурса:

  • Соединения: сколько одновременно активных клиентов и keepalive-соединений вы держите.
  • Сеть: пропускная способность и задержки между клиентами, Nginx и upstream.
  • Диск: чтение статики и запись логов.
  • Практическое правило: оптимизации стоит делать после того, как вы можете измерять эффект. Минимальный набор измерений вы уже знаете из прошлой темы:

  • access log с таймингами (upstream_response_time)
  • error log для причин 4xx/5xx
  • базовые метрики соединений через stub_status
  • Настройка процессов и лимитов соединений

    worker_processes и worker_connections

    Nginx обслуживает запросы рабочими процессами (workers). На старте обычно достаточно автоматической настройки:

    Документация: Директива worker_processes

    Максимум соединений приблизительно ограничен как:

  • число worker-процессов умножить на лимит соединений на worker.
  • Лимит соединений задаётся так:

    Документация: Директива worker_connections

    Важно понимать:

  • worker_connections ограничивает все соединения (включая соединения к upstream).
  • реальный потолок часто упирается в системный лимит файловых дескрипторов (в Linux это то, сколько одновременно открытых сокетов/файлов может иметь процесс).
  • Типичные продакшен-настройки в events

    Документация: Директива multi_accept

    multi_accept on; позволяет worker-у принимать сразу несколько новых соединений за одно событие, что иногда помогает при всплесках подключений.

    Оптимизация отдачи статики

    sendfile, tcp_nopush, tcp_nodelay

    Если Nginx раздаёт файлы с диска, обычно включают:

    Документация:

  • Директива sendfile
  • Директива tcp_nopush
  • Директива tcp_nodelay
  • Смысл на практическом уровне:

  • sendfile уменьшает лишние копирования данных при отдаче файлов.
  • tcp_nopush помогает эффективнее «упаковывать» данные в крупные сегменты при отправке больших файлов.
  • tcp_nodelay уменьшает задержки для небольших ответов (особенно в keepalive-сценариях).
  • open_file_cache

    Когда у вас много запросов к статике, Nginx тратит время на проверки файлов (существование, метаданные). Часть этого можно кэшировать:

    Документация: Директива open_file_cache

    Практический смысл параметров:

  • max ограничивает размер кэша.
  • inactive удаляет записи, к которым не обращались.
  • valid задаёт частоту перепроверки.
  • Кэширование в браузере: Cache-Control и версионирование

    Самая дешёвая оптимизация — заставить клиент не скачивать одно и то же повторно. Для файлов, которые меняются только при релизе (например, app.8f3c1.js), задают долгий кэш:

    Документация:

  • Директива proxy_cache_path
  • Директива proxy_cache
  • Директива proxy_cache_valid
  • Переменная binary_remote_addr zone=api_ratelimit:10m rate=10r/s;
  • }

    server { location /api/ { limit_req zone=api_ratelimit burst=20 nodelay; proxy_pass http://api_backend; } }

    Документация:

  • Директива limit_conn_zone
  • Директива limit_conn
  • Ограничение размера тела запроса

    Полезно, чтобы не принимать огромные загрузки там, где они не нужны:

    Документация: Директива client_max_body_size

    Практика продакшена: структура конфигурации и безопасные изменения

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

    Обычно удобно держать:

  • один файл с общими настройками http (gzip, лог-формат, лимиты)
  • отдельные файлы на каждый сайт/домен (server-блоки)
  • отдельные сниппеты для повторяющихся кусков (заголовки прокси, TLS-политики)
  • Ключевой навык из прошлых статей, который здесь становится обязательным:

  • смотреть итоговую конфигурацию через nginx -T
  • Стандартный безопасный цикл выката

  • Внести изменения в конфиги.
  • Проверить:
  • Документация: Опции командной строки nginx

  • Применить без полного простоя:
  • При reload Nginx перечитывает конфиг и делает мягкую перезагрузку worker-процессов.

    Документация: Управление процессом nginx

    Не забывайте про default_server

    В продакшене полезно явно закрывать неожиданные домены и уменьшать риск случайной «утечки» не того сайта:

    Это также помогает диагностике: вы сразу видите, что запрос пришёл с неправильным Host.

    Производственная наблюдаемость: что логировать для производительности

    Если Nginx работает как reverse proxy, формат access log должен отвечать на вопрос куда ушёл запрос и сколько ждал upstream.

    Пример формата:

    Документация: Модуль логирования

    Что это даёт на практике:

  • рост rt при стабильном urt часто означает проблему сети/клиента
  • рост urt означает, что тормозит upstream
  • upstream_addr помогает локализовать проблемы до конкретной реплики
  • Чеклист базовой производительной конфигурации

    Таблица ниже — не «магическая» настройка, а набор безопасных стартовых направлений.

    | Область | Что включить | Зачем | Где смотреть эффект | |---|---|---|---| | Процессы | worker_processes auto; | использовать доступные CPU | нагрузка CPU, задержки | | Соединения | worker_connections | выдерживать пик соединений | stub_status, 499/504 | | Статика | sendfile on; | быстрее отдавать файлы | request_time, CPU | | Файлы | open_file_cache | меньше системных вызовов | CPU, request_time | | Сжатие | gzip on; | меньше трафика | размер ответов, скорость загрузки | | Upstream | keepalive | меньше рукопожатий к бэкенду | upstream_response_time, RPS | | Таймауты | proxy_*_timeout | не держать зависшие запросы | доля 504, активные соединения | | Защита | limit_req, limit_conn | переживать всплески и атаки | доля 429/503, стабильность |

    Итоги

  • Оптимизация Nginx в продакшене начинается с измерений: тайминги в access log, error log и базовые метрики.
  • Для нагрузки важны настройки процессов, лимитов соединений и keepalive как к клиентам, так и к upstream.
  • Для статики обычно дают заметный эффект sendfile и корректное кэширование в браузере.
  • Для reverse proxy критичны таймауты, буферизация и (по возможности) keepalive к upstream.
  • Продакшен-практика — это безопасные выкаты (nginx -treload), понятная структура конфигов и наблюдаемость через логи.