Nginx (читается «энджин-икс») — это программа с открытым исходным кодом, которая принимает HTTP-запросы и либо сама отдает ответ (файлы сайта), либо передает запрос дальше — приложению на Python, PHP, Node.js. В первой роли Nginx работает как веб-сервер, во второй — как обратный прокси, а если приложений несколько, то еще и как балансировщик нагрузки.
Содержание
Ниже — устройство, плюсы и минусы, сравнение с Apache и минимальный конфиг с проверкой. Примеры проверены 23.09.2026 на Ubuntu 24.04 (пакет nginx 1.24.0) и в официальном Docker-образе nginx:stable-alpine (1.30.5).
Три роли Nginx и близкие термины
Эти роли часто смешивают, хотя это разные задачи:
| Роль | Что делает | Пример |
|---|---|---|
| Веб-сервер | Отдает файлы с диска: HTML, CSS, картинки | root /var/www/mysite; |
| Обратный прокси | Принимает запрос от клиента и пересылает его приложению, ответ возвращает клиенту | proxy_pass http://app; |
| Балансировщик | Распределяет запросы между несколькими копиями приложения | блок upstream с двумя server |
| TLS-терминатор | Принимает HTTPS, расшифровывает и дальше общается с приложением | listen 443 ssl; + сертификат |
Обратный прокси стоит перед серверами и защищает их от клиента. Прямой прокси стоит перед клиентами и ходит в интернет от их имени. Nginx обычно используют в первой роли.
Кроме HTTP, Nginx умеет проксировать TCP/UDP (модуль stream) и почтовые протоколы.
Как Nginx работает
Nginx запускает один master-процесс и несколько worker-процессов. Master читает конфигурацию и управляет воркерами, а запросы обслуживают воркеры. Число воркеров задает worker_processes, и значение auto означает «по числу ядер процессора».
Главная особенность — событийная модель. Воркер не выделяет отдельный поток на каждое соединение и не ждет, пока медленный клиент дочитает ответ. Он держит тысячи соединений и через механизм ОС (epoll в Linux, kqueue во FreeBSD и macOS) узнает, какое из них готово к чтению или записи. Поэтому при большом числе одновременных подключений Nginx расходует мало памяти.
Лимит соединений на воркер задает worker_connections: в пакете Ubuntu 24.04 стоит 768, в официальном Docker-образе — 1024. Это именно соединения, включая соединения к приложениям за прокси, а не «запросы пользователя».
Упрощение, о котором стоит помнить: Nginx сам не выполняет PHP или Python. Динамику он передает внешнему процессу — PHP-FPM по протоколу FastCGI, приложению по HTTP (proxy_pass), uWSGI или SCGI.
Плюсы и минусы Nginx
| Плюсы | Минусы |
|---|---|
| Держит много одновременных соединений при малом расходе памяти | Нет .htaccess: правила для каталогов меняет только администратор в основном конфиге |
| Быстро отдает статические файлы | Сам не исполняет PHP/Python — нужен PHP-FPM или сервер приложений |
| Один инструмент закрывает веб-сервер, прокси, балансировку, кеш, TLS | Синтаксис конфига и порядок выбора location новичку неочевидны |
Перезагрузка конфига без разрыва соединений (reload) |
Часть функций (активные проверки здоровья, API управления) есть только в платной NGINX Plus |
| Свободная лицензия (BSD-подобная), пакеты во всех популярных дистрибутивах | Сборка для Windows официально считается бета-версией, для продакшена не рекомендуется |
Модуль либо вкомпилирован в сборку, либо подключается как динамический через load_module; состав сборки показывает nginx -V.
Nginx или Apache
| Критерий | Nginx | Apache HTTP Server 2.4 |
|---|---|---|
| Модель обработки | Событийная, воркеры | Модули MPM: prefork, worker, event |
| Настройка на уровне каталога | Нет | Да, через .htaccess (если разрешено AllowOverride) |
| PHP | Через PHP-FPM | Через PHP-FPM или встроенный mod_php |
| Типичная роль | Фронт: статика, прокси, TLS | Сервер приложений, shared-хостинг |
Частая связка — Nginx на входе, за ним Apache или приложение. Вывод «Nginx всегда быстрее» неверен: у Apache есть событийный MPM event, а узким местом под нагрузкой обычно оказывается приложение или база.
Минимальный конфиг: статика + прокси + балансировка
Сначала рабочий пример целиком. Установка в Ubuntu:
sudo apt update
sudo apt install nginx
nginx -v
Перед правкой (особенно если на сервере уже работают другие сайты): держите открытой текущую SSH-сессию, сохраните копию конфигурации под уникальным именем и запишите путь к ней — это ваша точка отката.
B=/etc/nginx.bak-$(date +%F-%H%M%S)
test ! -e "$B" && sudo cp -a /etc/nginx "$B" && echo "Копия: $B"
Имя только с датой (/etc/nginx.bak-$(date +%F)) не годится для повторных правок: при втором запуске за день такой каталог уже есть, и cp -a не заменит его, а положит новую копию внутрь, в /etc/nginx.bak-ДАТА/nginx. После этого непонятно, какую версию восстанавливать. Время в имени и проверка test ! -e исключают копирование поверх существующего пути. Полный порядок правки, проверки и отката — в разделе «Как безопасно менять конфиг Nginx» ниже.
Файл /etc/nginx/sites-available/mysite — так раскладывают сайты пакеты Debian и Ubuntu. В RHEL, Rocky, AlmaLinux и в пакетах с nginx.org каталогов sites-* нет: тот же блок кладут в /etc/nginx/conf.d/mysite.conf, без симлинка. Два учебных «приложения» здесь изображает сам Nginx на портах 9001 и 9002 — так пример запускается без Python или Node.js. В реальном проекте на их месте ваше приложение.
# Два учебных бэкенда: вместо них обычно ваше приложение (Python, Node.js, PHP-FPM)
server {
listen 127.0.0.1:9001;
return 200 "app-1 got $request_uri\n";
}
server {
listen 127.0.0.1:9002;
return 200 "app-2 got $request_uri\n";
}
upstream app {
zone app 64k;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
server {
listen 80;
server_name example.local;
server_tokens off;
root /var/www/mysite;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location /api/ {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Включаем сайт, проверяем синтаксис и применяем без остановки сервера:
sudo mkdir -p /var/www/mysite
echo "<h1>Hello from Nginx</h1>" | sudo tee /var/www/mysite/index.html
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
curl -H "Host: example.local" http://127.0.0.1/
for i in 1 2 3 4; do curl -s -H "Host: example.local" http://127.0.0.1/api/users; done
Результат: nginx -t сообщает syntax is ok и test is successful, первый curl возвращает страницу, а в этом последовательном прогоне запросы к /api/ чередовались между двумя бэкендами:
<h1>Hello from Nginx</h1>
app-1 got /api/users
app-2 got /api/users
app-1 got /api/users
app-2 got /api/users
Что здесь происходит
server_name example.local— Nginx выбирает блокserverпо заголовкуHost. Без-H "Host: ..."запрос попадет в сайт по умолчанию (в Ubuntu он включен из коробки), иcurlпокажет страницу «Welcome to nginx!».location /отдает файлы изroot, аtry_files ... =404возвращает 404, если файла нет, вместо попытки угадать.upstream app— группа бэкендов, по умолчанию round-robin. Директиваzoneхранит состояние группы в общей памяти, которую видят все воркеры; с ней четыре последовательных запроса выше чередовались 1-2-1-2, а без нее у каждого воркера свое состояние, и в прогоне на двух воркерах порядок былapp-1, app-1, app-2, app-1. Строгой очередности алгоритм не обещает: параллельные запросы, отказы и временно отключенные серверы меняют выбор, поэтому в приложении на конкретный порядок не полагайтесь.- Если бэкенд не принимает соединение, Nginx по умолчанию (
proxy_next_upstream error timeout) передает запрос другому серверу: при остановленном втором бэкенде все четыре запроса вернули 200, причем и GET, и POST. Для POST это работает именно потому, что соединение не установилось и запрос еще не ушел бэкенду. Если же запрос уже отправлен, а бэкенд упал или не ответил вовремя, неидемпотентные запросы (POST, PATCH, LOCK) по умолчанию на другой сервер не передаются. Параметрnon_idempotentснимает это ограничение, но тогда операция может выполниться дважды: включайте его, только если приложение защищено от дублей. И даже без повтора клиент после такого обрыва не знает наверняка, выполнилась ли операция. server_tokens offскрывает версию: в ответеServer: nginxвместоServer: nginx/1.24.0 (Ubuntu).- Бэкенды слушают только
127.0.0.1, поэтому снаружи в обход Nginx к ним не достучаться.
Одна косая черта в proxy_pass меняет URL
Это частая ловушка. С proxy_pass http://app; приложение получает путь целиком: app-1 got /api/users. Если написать proxy_pass http://app/;, Nginx заменит совпавшую часть /api/ на /, и приложение увидит app-1 got /users. Какой вариант нужен, зависит от того, какие пути ждет приложение.
Если не получилось
Симптом: nginx -t падает. Уберем точку с запятой после root /var/www/mysite:
2026/09/23 15:57:34 [emerg] 2644#2644: invalid number of arguments in "root" directive in /etc/nginx/sites-enabled/mysite:23
nginx: configuration file /etc/nginx/nginx.conf test failed
Так выглядит вывод в Ubuntu 24.04 (дата и номер процесса у вас будут свои). В официальном образе и пакетах с nginx.org строка ошибки начинается с nginx: [emerg], текст тот же.
Ошибка указывает на строку 23, хотя пропуск в строке 22: без ; Nginx склеил root со следующей директивой index. Исправление — вернуть ; и снова запустить nginx -t. Если все же выполнить nginx -s reload (или systemctl reload nginx) с ошибкой, команда завершится с ошибкой, а Nginx продолжит работать со старым конфигом. А вот restart с такой ошибкой сервер не поднимет.
Симптом: 502 Bad Gateway на /api/. Nginx жив, но не достучался до приложения. В error.log будет строка вида connect() failed (111: Connection refused) while connecting to upstream с адресом бэкенда. Проверьте, что приложение запущено и слушает тот адрес и порт, что указан в upstream.
Симптом: вместо вашего сайта «Welcome to nginx!». server_name не совпал с Host, ответил сайт по умолчанию. Проверьте домен и ls -l /etc/nginx/sites-enabled/.
Как безопасно менять конфиг Nginx (Ubuntu/Debian)
Порядок ниже — для Ubuntu/Debian с systemd; в других дистрибутивах отличаются пути к файлам сайтов (см. выше), остальные команды те же.
- Доступ: работайте в открытой SSH-сессии и не закрывайте ее до конца проверки. Правка Nginx не трогает SSH, но ошибка в файрволе или сети может.
- Копия под уникальным именем, как в блоке «Перед правкой»:
B=/etc/nginx.bak-$(date +%F-%H%M%S), затемtest ! -e "$B" && sudo cp -a /etc/nginx "$B". Путь из$Bзапишите: переменная живет только в текущей сессии. - Правка файла сайта, а не общего
nginx.conf. sudo nginx -t— это проверка синтаксиса и того, что файлы из конфига открываются, а не того, что сайт работает правильно.sudo nginx -Tдополнительно покажет итоговый конфиг целиком: видно, какие файлы реально подключены.sudo systemctl reload nginx, а неrestart: старые воркеры доработают текущие запросы. Команда должна завершиться без ошибки, свежие строки[emerg]смотрите вsudo tail /var/log/nginx/error.log.- Проверка ответа: локально
curl -I -H "Host: example.local" http://127.0.0.1/, с другой машины — по реальному домену, а для HTTPS черезcurl -I --resolve example.com:443:IP_сервера https://example.com/, чтобы проверить иHost, и сертификат по SNI. Ждем ожидаемый код (200 или 301), а не страницу «Welcome to nginx!». - Откат, если сломалось: вернуть файл именно из той копии, что сделана перед этой правкой (
sudo cp -a "$B"/sites-available/mysite /etc/nginx/sites-available/, где$B— записанный путь), или убрать симлинк изsites-enabled, затем сноваnginx -t,reloadиcurl.
И две оговорки о безопасности. Заголовку X-Forwarded-For приложение может доверять только если оно недоступно напрямую: клиент способен прислать свой поддельный X-Forwarded-For, а $proxy_add_x_forwarded_for лишь дописывает к нему реальный адрес. А при включении файрвола сначала разрешите SSH, потом 80 и 443, и только затем включайте его — иначе можно потерять доступ к серверу. В Ubuntu с ufw это sudo ufw allow OpenSSH, sudo ufw allow 'Nginx Full', sudo ufw enable и проверка sudo ufw status до выхода из текущей SSH-сессии.
Форки и родственные проекты
Nginx создал Игорь Сысоев, первая публичная версия вышла в 2004 году. С 2019 года проект принадлежит F5, которая развивает открытую версию и платную NGINX Plus. Открытая версия выходит двумя ветками: mainline с новыми функциями и stable только с исправлениями; на сентябрь 2026 это 1.31.x и 1.30.x, для продакшена обычно берут stable или пакет дистрибутива (в Ubuntu 24.04 — 1.24.0 с патчами безопасности от Ubuntu). Есть форки: Angie — российский проект бывших разработчиков Nginx с совместимым синтаксисом, и freenginx — форк, который с 2024 года ведет Максим Дунин, бывший ключевой разработчик Nginx. Базовые директивы (server, location, proxy_pass, upstream) в них работают так же, но расширения и номера версий у каждого проекта свои.
Выводы
- Nginx — это веб-сервер, обратный прокси, балансировщик и TLS-терминатор в одной программе; роли удобно различать по задаче.
- Сильная сторона — событийная модель: много соединений при малом расходе памяти. Динамику он передает приложению или PHP-FPM.
- Главные минусы — нет
.htaccess, нужен отдельный сервер для PHP/Python, неочевидная логикаlocationиproxy_pass. - Рабочий цикл изменений: копия -> правка ->
nginx -t->reload-> проверкаcurl-> откат при ошибке.
Где применяется / связь с практикой
Освойте тему на практике
Nginx стоит перед большинством веб-проектов, поэтому его настройка входит в базовые задачи Linux-администратора и DevOps-инженера: публикация сайта, прокси к приложению, HTTPS, разбор 502 по логам. Системно разобрать администрирование Linux, включая веб-серверы, сеть и диагностику, можно на курсе «Administrator Linux. Professional». Попробовать формат и задать вопросы преподавателям можно на бесплатных открытых уроках Otus.
FAQ
Можно ли запустить Nginx на Windows?
Официальная сборка для Windows есть, но разработчики считают ее бета-версией с ограничениями производительности. Для разработки на Windows удобнее запускать Nginx в Docker или WSL.
Чем reload отличается от restart?
reload перечитывает конфиг и плавно заменяет воркеры без разрыва соединений, а при ошибке в конфиге оставляет старую версию. restart останавливает и заново запускает сервер, и с ошибкой в конфиге Nginx не поднимется.
Нужен ли Nginx, если приложение само умеет отвечать по HTTP?
Не обязательно, но на практике его ставят перед приложением, чтобы отдавать статику, держать TLS и медленных клиентов, распределять нагрузку и не открывать порт приложения наружу.



