Nginx — это высокопроизводительный веб-сервер, обратный прокси-сервер и балансировщик нагрузки. Архитектура Nginx основана на модели master-процесса и worker-процессов. Master-процесс читает и обрабатывает конфигурацию, а также управляет worker-процессами, которые выполняют фактическую обработку запросов.
Структура конфигурационного файла
Конфигурация Nginx имеет иерархическую блочную структуру, где директивы организованы в контексты. Основной конфигурационный файл обычно находится по адресу /etc/nginx/nginx.conf.
Основные контексты конфигурации
Main (главный) контекст — глобальная область, содержащая директивы, которые влияют на весь экземпляр Nginx.
Events контекст — управляет настройками обработки соединений.
HTTP контекст — содержит всю HTTP-связанную конфигурацию.
Server контекст — определяет виртуальные хосты и специфичные для сервера настройки.
Location контекст — специфичная для URL конфигурация внутри server-блока.
Upstream контекст — определяет группы серверов для балансировки нагрузки.
Пример базовой структуры конфигурации
# Main контекст - глобальные директивы
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
# Events контекст
events {
worker_connections 1024;
use epoll;
}
# HTTP контекст
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Server контекст
server {
listen 80;
server_name example.com;
root /var/www/html;
# Location контекст
location / {
try_files $uri $uri/ =404;
}
}
}
Процессы и соединения
Worker Processes
Директива worker_processes определяет количество рабочих процессов для обработки запросов. Каждый worker-процесс является однопоточным.
worker_processes auto; # автоматически определяет количество CPU ядер
Как это работает: Если Nginx выполняет CPU-интенсивные операции (например, SSL или gzip), и у вас 2 или более CPU/ядер, то вы можете установить worker_processes равным количеству CPU или ядер. Значение auto автоматически определяет оптимальное количество на основе доступных ядер.
Worker Connections
Директива worker_connections определяет максимальное количество одновременных соединений, которые может открыть один worker-процесс.
events {
worker_connections 1024;
}
Расчет максимального количества клиентов:
max_clients = worker_processes × worker_connections
Например, если у вас 4 worker-процесса и 1024 соединения на процесс, вы можете обслуживать до 4096 клиентов одновременно.
Важное замечание: При использовании Nginx в качестве reverse proxy, это число нужно делить на 2, поскольку каждое клиентское соединение требует соединения с backend-сервером.
Оптимизация worker_connections
По умолчанию значение составляет 512 или 768. Вы можете увеличить это значение до лимита системы, определяемого командой ulimit -n.
events {
worker_connections 1024;
use epoll; # для Linux
multi_accept on; # принимать несколько соединений за один цикл событий
}
Директива Server
Server-блок определяет виртуальный хост — конфигурацию для конкретного домена или IP-адреса.
Listen директива
Определяет, на каком порту и адресе сервер будет слушать входящие соединения.
server {
listen 80; # IPv4 на порту 80
listen [::]:80; # IPv6 на порту 80
listen 443 ssl http2; # HTTPS с HTTP/2
listen 192.168.1.10:8080; # конкретный IP и порт
}
Server_name директива
Определяет доменное имя (или имена), которые будут обрабатываться этим server-блоком.
server {
server_name example.com www.example.com; # несколько доменов
}
server {
server_name *.example.com; # wildcard
}
server {
server_name ~^(?<subdomain>.+)\.example\.com$; # regex
}
Как Nginx выбирает server-блок:
- Точное совпадение имени
- Самое длинное совпадение, начинающееся с *
- Самое длинное совпадение, заканчивающееся на *
- Первое совпадение по регулярному выражению
- Default server (указанный с
default_server в listen)
Директива Location
Location-блоки определяют, как обрабатывать запросы в зависимости от URI.
Синтаксис и модификаторы
location [modifier] path {
# конфигурация
}
Модификаторы:
= — точное совпадение (наивысший приоритет)
^~ — преимущественное префиксное совпадение (останавливает поиск regex)
~ — regex с учетом регистра
~* — regex без учета регистра
- (без модификатора) — префиксное совпадение
Порядок приоритета location
- Точные совпадения
=
- Преимущественные префиксы
^~
- Регулярные выражения
~ и ~* (в порядке появления в файле)
- Префиксные совпадения (самый длинный префикс имеет приоритет)
Примеры location
# Точное совпадение - наивысший приоритет
location = /exact {
return 200 "Exact match";
}
# Преимущественный префикс - останавливает regex
location ^~ /images/ {
root /var/www;
}
# Regex с учетом регистра
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
}
# Regex без учета регистра
location ~* \.(jpg|png|gif)$ {
expires 1y;
}
# Префиксное совпадение
location /api/ {
proxy_pass http://backend;
}
# Дефолтный обработчик
location / {
root /var/www/html;
index index.html;
}
Root и Alias директивы
Root директива
Директива root устанавливает корневую директорию для запросов. Полный путь формируется путем добавления URI запроса к значению root, включая часть location.
location /images/ {
root /var/www;
}
Для запроса /images/logo.png файл будет искаться по пути: /var/www/images/logo.png.
Alias директива
Директива alias заменяет часть URI, указанную в location, на путь из alias. Часть location НЕ добавляется к пути.
location /images/ {
alias /var/www/static/;
}
Для запроса /images/logo.png файл будет искаться по пути: /var/www/static/logo.png.
Важное различие: С root путь location добавляется к корневому пути, с alias — заменяется.
Try_files директива
Директива try_files проверяет существование файлов в указанном порядке и обслуживает первый найденный.
Синтаксис
try_files file1 file2 ... uri;
try_files file1 file2 ... =code;
Примеры использования
# Базовое использование для SPA приложений
location / {
try_files $uri $uri/ /index.html;
}
Как это работает:
- Сначала проверяет, существует ли файл
$uri
- Если нет, проверяет, является ли
$uri/ директорией
- Если нет, отдает
/index.html
# С named location для проксирования
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://backend-server;
}
# С кодом ошибки
location / {
try_files $uri $uri/ =404;
}
Важно: При использовании try_files внутри location, если последний параметр — URI, Nginx выполнит внутренний редирект.
Reverse Proxy конфигурация
Proxy_pass директива
Директива proxy_pass перенаправляет запросы на proxied-сервер.
location /api/ {
proxy_pass http://127.0.0.1:8000;
}
Важные proxy заголовки
location / {
proxy_pass http://backend;
# Передает оригинальный Host header
proxy_set_header Host $host;
# IP адрес клиента
proxy_set_header X-Real-IP $remote_addr;
# Цепочка proxy серверов
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Протокол (http или https)
proxy_set_header X-Forwarded-Proto $scheme;
}
Почему это важно: По умолчанию Nginx перезаписывает Host header на адрес proxied-сервера. Приложению на backend нужен оригинальный Host header, чтобы правильно обрабатывать запросы.
Proxy_redirect
# Перезаписывает Location и Refresh заголовки в ответах от proxied-сервера
proxy_redirect http://localhost:8000/ http://example.com/;
# Или для всех URL
proxy_redirect http://localhost:8000/ /;
Отключение буферизации
location /stream/ {
proxy_pass http://backend;
proxy_buffering off; # для приложений с низкой задержкой
}
Upstream и балансировка нагрузки
Директива upstream определяет группу серверов для балансировки нагрузки.
Базовая конфигурация
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080;
}
server {
location / {
proxy_pass http://backend;
}
}
Методы балансировки
Round Robin (по умолчанию) — запросы распределяются последовательно.
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
Least Connections — запросы направляются на сервер с наименьшим количеством активных соединений.
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
IP Hash — клиент всегда направляется на один и тот же сервер на основе IP.
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
Weight — распределение нагрузки с учетом весов.
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
}
Параметры серверов в upstream
upstream backend {
server backend1.example.com:8080 weight=5;
server backend2.example.com:8080 max_fails=3 fail_timeout=30s;
server backend3.example.com:8080 max_conns=100;
server backend4.example.com:8080 backup; # используется только если основные недоступны
server backend5.example.com:8080 down; # временно исключен
}
SSL/TLS конфигурация
Базовая HTTPS конфигурация
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
# Пути к сертификатам
ssl_certificate /etc/nginx/certs/ssl_certificate.crt;
ssl_certificate_key /etc/nginx/certs/ssl_certificate.key;
# Протоколы SSL
ssl_protocols TLSv1.2 TLSv1.3;
# Шифры
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /var/www/html;
}
}
Редирект HTTP на HTTPS
# Редирект всех HTTP запросов на HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS сервер
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/cert.key;
location / {
root /var/www/html;
}
}
Каноническая форма URL
# Редирект с example.com на www.example.com
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/cert.key;
return 301 https://www.example.com$request_uri;
}
# Основной сервер
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/cert.key;
location / {
root /var/www/html;
}
}
Gzip сжатие
Gzip сжатие уменьшает размер передаваемых файлов, ускоряя загрузку сайта.
Основная конфигурация
http {
# Включить gzip
gzip on;
# Уровень сжатия (1-9)
# 5 - оптимальный баланс между размером и CPU
gzip_comp_level 5;
# Минимальная длина ответа для сжатия
gzip_min_length 256;
# Включить сжатие для proxied запросов
gzip_proxied any;
# MIME типы для сжатия
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/xml+rss
application/xhtml+xml
image/svg+xml;
# Добавить Vary: Accept-Encoding header
gzip_vary on;
}
Как это работает: Когда браузер делает запрос, сервер сжимает файл с помощью gzip перед отправкой. Браузер распаковывает его перед отображением пользователю. Уровень сжатия 5 обеспечивает около 75% уменьшения размера для большинства текстовых файлов.
Примечание: text/html всегда включен в gzip по умолчанию, его не нужно указывать явно.
Security Headers
Security headers защищают от различных атак (XSS, clickjacking, MIME-sniffing).
Основные заголовки безопасности
# В http или server контексте
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none';" always;
Описание заголовков:
- Strict-Transport-Security (HSTS) — принудительное использование HTTPS
- X-Frame-Options — защита от clickjacking, запрещает встраивание в iframe
- X-Content-Type-Options — запрещает MIME-sniffing браузерами
- X-XSS-Protection — включает встроенный XSS фильтр браузера
- Content-Security-Policy — контролирует, какие ресурсы можно загружать
- Referrer-Policy — контролирует передачу Referer header
Параметр always: Гарантирует, что Nginx добавит заголовки даже для ответов с кодами 4xx и 5xx.
Создание переиспользуемого snippet
# /etc/nginx/snippets/security-headers.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Использование в server-блоке:
server {
listen 443 ssl http2;
server_name example.com;
include snippets/security-headers.conf;
location / {
root /var/www/html;
}
}
Таймауты
Таймауты контролируют, как долго Nginx ждет различных событий.
Основные директивы таймаутов
http {
# Таймаут для чтения заголовков запроса от клиента
client_header_timeout 60s;
# Таймаут для чтения тела запроса от клиента
client_body_timeout 60s;
# Время, в течение которого keepalive соединение остается открытым
keepalive_timeout 75s;
# Таймаут для отправки ответа клиенту
send_timeout 60s;
}
Client_body_timeout
Определяет, сколько времени Nginx будет ждать отправки тела запроса клиентом. Важно для загрузки больших файлов.
# Для сайтов с загрузкой больших файлов
client_body_timeout 300s;
Keepalive_timeout
Определяет, как долго keepalive соединение остается открытым после отправки ответа.
keepalive_timeout 65s;
Как это работает: После отправки ответа клиенту соединение не закрывается сразу, а остается открытым указанное время. Это позволяет повторно использовать соединение для последующих запросов, избегая накладных расходов на установку нового TCP соединения.
Оптимизация: Высокое значение позволяет повторно использовать соединения, но потребляет больше ресурсов сервера. Для сайтов с высокой нагрузкой можно уменьшить до 30s.
Пример для API с большими загрузками
location /api/upload {
client_header_timeout 120s;
client_body_timeout 300s;
client_max_body_size 100m;
proxy_pass http://backend;
proxy_read_timeout 300s;
proxy_connect_timeout 60s;
}
Размеры буферов
Client_body_buffer_size
Определяет размер буфера для чтения тела запроса клиента.
# По умолчанию 8k или 16k
client_body_buffer_size 16k;
Как это работает: Если размер тела запроса превышает размер буфера, Nginx записывает его во временный файл на диске. Это замедляет обработку из-за дополнительных операций I/O.
Оптимизация: Для API с большими загрузками можно увеличить размер буфера, но не устанавливайте его слишком большим, чтобы избежать уязвимостей к DoS атакам.
Client_max_body_size
Ограничивает максимальный размер тела запроса клиента.
http {
client_max_body_size 10M;
}
# Или для конкретного location
location /upload {
client_max_body_size 100M;
}
По умолчанию: 1M. Если клиент отправляет файл больше этого размера, Nginx возвращает ошибку 413 (Request Entity Too Large).
PHP-FPM конфигурация
Базовая настройка для PHP
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
# Обработка PHP файлов
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# Для UNIX сокета
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
# Или для TCP/IP
# fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Запрет доступа к .htaccess файлам
location ~ /\.ht {
deny all;
}
}
Как это работает: Когда запрашивается файл .php, Nginx передает запрос PHP-FPM через FastCGI протокол. PHP-FPM выполняет скрипт и возвращает результат обратно Nginx.
Разные версии PHP для разных сайтов
server {
server_name site1.com;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
include fastcgi_params;
}
}
server {
server_name site2.com;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
}
}
Rewrite и редиректы
Return директива
Директива return — самый эффективный способ создания редиректов.
# Постоянный редирект (301)
location /old-page {
return 301 /new-page;
}
# Временный редирект (302)
location /temp {
return 302 /temporary-location;
}
# Редирект на другой домен
server {
server_name old-domain.com;
return 301 https://new-domain.com$request_uri;
}
Почему return лучше rewrite: return немедленно останавливает обработку и отправляет редирект, без дополнительных проверок. Это быстрее и проще в понимании.
Rewrite директива
Директива rewrite использует регулярные выражения для изменения URI.
Синтаксис:
rewrite regex replacement [flag];
Флаги:
last — останавливает обработку rewrite и начинает новый поиск location
break — останавливает обработку rewrite в текущем контексте
redirect — временный редирект (302)
permanent — постоянный редирект (301)
Примеры rewrite
# Простой rewrite с захватом групп
location /data/ {
rewrite ^(/data/.*)/geek/(\w+)\.?.*$ $1/linux/$2.html last;
}
# /data/distro/geek/test.php -> /data/distro/linux/test.html
Как это работает: $1 и $2 захватывают части URI, заключенные в скобки () в регулярном выражении.
# Rewrite для контроллера
location /linux/ {
rewrite ^/linux/(.*)$ /linux.php?distro=$1 last;
}
# /linux/ubuntu -> /linux.php?distro=ubuntu
# Условный rewrite
if ($scheme = "http") {
rewrite ^ https://example.com$uri permanent;
}
Редирект с сохранением параметров
location /old-path/ {
return 301 /new-path$request_uri;
}
Переменные Nginx
Nginx предоставляет множество встроенных переменных для использования в конфигурации.
Основные переменные запроса
# IP адрес клиента
$remote_addr
# Порт клиента
$remote_port
# Полный URI запроса с параметрами
$request_uri
# Нормализованный URI (после rewrite)
$uri
# HTTP метод (GET, POST, etc.)
$request_method
# Протокол запроса (http или https)
$scheme
# Host header из запроса
$host
# Доменное имя сервера
$server_name
# Порт сервера
$server_port
# Query string (параметры после ?)
$args или $query_string
Пример использования переменных
# Логирование с переменными
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
# Установка заголовков
location / {
proxy_pass http://backend;
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;
}
# Условная логика
if ($request_method = POST) {
return 405;
}
Переменные для доступа к параметрам
# Доступ к конкретному query параметру
$arg_name # для параметра ?name=value
# Пример
if ($arg_debug = "true") {
return 200 "Debug mode";
}
Map директива
Директива map создает новые переменные на основе значений других переменных.
Синтаксис:
map $source_variable $destination_variable {
default default_value;
value1 result1;
value2 result2;
~regex result3;
}
Примеры использования map
# Редирект поддоменов
map $host $redirect_host {
default "example.org";
~^(?<subdomain>\S+)\.example\.com$ $subdomain.example.org;
}
server {
server_name .example.com;
return 301 https://$redirect_host$request_uri;
}
# Определение backend на основе User-Agent
map $http_user_agent $backend {
default backend_default;
~*bot backend_bots;
~*mobile backend_mobile;
}
server {
location / {
proxy_pass http://$backend;
}
}
# Установка переменной для блокировки IP
map $remote_addr $blocked {
default 0;
192.168.1.10 1;
10.0.0.5 1;
}
server {
if ($blocked) {
return 403;
}
}
Важно: map директива может использоваться только в http контексте, а не внутри server или location.
Rate Limiting (ограничение частоты запросов)
Rate limiting защищает сервер от перегрузки и DoS атак.
Limit_req (ограничение запросов)
http {
# Определяем зону для отслеживания
limit_req_zone $binary_remote_addr zone=limitbyip:10m rate=10r/s;
# Статус для отклоненных запросов
limit_req_status 429;
server {
location /api/ {
# Применяем ограничение
limit_req zone=limitbyip burst=20 nodelay;
proxy_pass http://backend;
}
}
}
Параметры:
$binary_remote_addr — ключ для идентификации клиентов (IP адрес)
zone=limitbyip:10m — имя зоны и размер памяти (10 МБ)
rate=10r/s — максимальная частота (10 запросов в секунду)
burst=20 — разрешает временные всплески до 20 запросов
nodelay — обрабатывает burst запросы немедленно, без задержки
Как это работает: Nginx отслеживает количество запросов от каждого IP адреса. Если частота превышает указанный лимит, запросы задерживаются (помещаются в очередь) или отклоняются с ошибкой 429.
Limit_conn (ограничение соединений)
http {
# Определяем зону
limit_conn_zone $binary_remote_addr zone=connlimit:10m;
server {
location /downloads/ {
# Максимум 5 одновременных соединений от одного IP
limit_conn connlimit 5;
root /var/www/files;
}
}
}
Множественные ограничения
http {
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;
server {
location / {
limit_req zone=perip burst=5 nodelay;
limit_req zone=perserver burst=10;
proxy_pass http://backend;
}
}
}
MIME типы
Default_type и mime.types
Nginx использует MIME типы для определения типа содержимого файлов.
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
}
Как это работает: Файл mime.types содержит сопоставление расширений файлов и MIME типов. Если расширение файла не найдено в mime.types, используется default_type.
application/octet-stream означает, что браузер будет скачивать файл как бинарный, вместо попытки отобразить его.
Добавление пользовательских MIME типов
http {
include mime.types;
types {
application/javascript mjs;
application/wasm wasm;
}
}
Логирование
Access log
http {
# Определение формата лога
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# Использование формата
access_log /var/log/nginx/access.log main;
}
Пользовательский формат лога
http {
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/custom.log custom;
}
Полезные переменные для логов:
$request_time — полное время обработки запроса
$upstream_response_time — время ответа backend сервера
$status — код HTTP ответа
$body_bytes_sent — количество отправленных байт
Error log
# Уровни: debug, info, notice, warn, error, crit, alert, emerg
error_log /var/log/nginx/error.log warn;
Отключение логов для статики
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
access_log off;
expires 1y;
}
Include директива
Директива include позволяет подключать внешние конфигурационные файлы.
http {
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
server {
include /etc/nginx/snippets/ssl-params.conf;
include /etc/nginx/snippets/security-headers.conf;
}
}
Преимущества использования include:
- Модульность конфигурации
- Переиспользование общих настроек
- Упрощение управления большими конфигурациями
Структура директорий
/etc/nginx/
├── nginx.conf # Главный файл
├── conf.d/ # Дополнительные конфигурации
│ └── default.conf
├── sites-available/ # Доступные сайты
│ ├── example.com.conf
│ └── test.com.conf
├── sites-enabled/ # Активные сайты (симлинки)
│ └── example.com.conf -> ../sites-available/example.com.conf
└── snippets/ # Переиспользуемые фрагменты
├── ssl-params.conf
└── security-headers.conf
If директива и её подводные камни
Директива if в Nginx работает не так, как ожидается в большинстве языков программирования.
Когда безопасно использовать if
Безопасно только с директивами return и rewrite:
if ($scheme = "http") {
return 301 https://$host$request_uri;
}
if ($request_method = POST) {
return 405;
}
Проблемы с if
# НЕПРАВИЛЬНО - может вызвать segmentation fault
location / {
if ($request_uri ~* "admin") {
proxy_pass http://admin_backend;
}
root /var/www/html;
}
Почему это проблема: if в Nginx оценивается на этапе конфигурации, а не на каждом запросе. Это может приводить к неожиданному поведению и ошибкам.
Альтернативы if
Используйте map вместо if:
map $request_uri $backend {
default http://default_backend;
~*admin http://admin_backend;
}
server {
location / {
proxy_pass $backend;
}
}
Используйте разные location блоки:
location ~* /admin {
proxy_pass http://admin_backend;
}
location / {
proxy_pass http://default_backend;
}
Events контекст и оптимизация производительности
Основные директивы events
events {
# Количество одновременных соединений на worker
worker_connections 1024;
# Метод обработки событий (зависит от ОС)
use epoll; # Linux
# use kqueue; # FreeBSD, macOS
# Принимать несколько соединений за раз
multi_accept on;
}
Методы обработки событий
Linux: epoll — наиболее эффективный метод для Linux систем.
FreeBSD/macOS: kqueue — оптимизированный для BSD систем.
Почему это важно: Эти методы используют механизмы ядра операционной системы для эффективной обработки тысяч соединений одновременно без блокировки.
Полная оптимизация производительности
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
# Основные настройки
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Таймауты
keepalive_timeout 65;
client_header_timeout 60;
client_body_timeout 60;
send_timeout 60;
# Буферы
client_body_buffer_size 16k;
client_max_body_size 10m;
# Gzip
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml;
# Кэширование открытых файлов
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
Проверка и перезагрузка конфигурации
Проверка синтаксиса
# Проверка конфигурации
sudo nginx -t
# Вывод:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
Управление Nginx
# Запуск
sudo systemctl start nginx
# Остановка
sudo systemctl stop nginx
# Перезапуск
sudo systemctl restart nginx
# Перезагрузка конфигурации без разрыва соединений
sudo systemctl reload nginx
# Или напрямую
sudo nginx -s reload
# Проверка статуса
sudo systemctl status nginx
Сигналы Nginx
# Изящная остановка (ждет завершения запросов)
sudo nginx -s quit
# Быстрая остановка
sudo nginx -s stop
# Перезагрузка конфигурации
sudo nginx -s reload
# Переоткрыть лог-файлы
sudo nginx -s reopen
Полный пример конфигурации production-сервера
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Логирование
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;
# Основные настройки
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Таймауты
keepalive_timeout 65;
client_header_timeout 60;
client_body_timeout 60;
send_timeout 60;
# Буферы
client_body_buffer_size 16k;
client_max_body_size 10m;
# Gzip сжатие
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml
application/xml+rss;
# Rate limiting
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_status 429;
# Upstream для балансировки
upstream backend {
least_conn;
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080 weight=2;
server backend3.example.com:8080 backup;
}
# Редирект HTTP на HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
# Редирект с example.com на www.example.com
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
return 301 https://www.example.com$request_uri;
}
# Основной сервер
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
root /var/www/html;
index index.php index.html;
# SSL
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none';" always;
# Логирование
access_log /var/log/nginx/example.com.access.log main;
error_log /var/log/nginx/example.com.error.log warn;
# Основной location
location / {
try_files $uri $uri/ /index.php?$args;
}
# API с rate limiting
location /api/ {
limit_req zone=general burst=20 nodelay;
proxy_pass http://backend;
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;
proxy_read_timeout 300s;
proxy_connect_timeout 60s;
}
# PHP обработка
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Статические файлы
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Запрет доступа к скрытым файлам
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Health check endpoint
location = /health {
access_log off;
return 200 "OK\n";
add_header Content-Type text/plain;
}
}
}
Заключение
Эта статья охватывает основные и продвинутые аспекты конфигурации Nginx:
- Архитектура — master и worker процессы, обработка соединений
- Структура конфигурации — иерархия контекстов и директив
- Location блоки — модификаторы и приоритеты обработки
- Reverse proxy — проксирование запросов на backend серверы
- Балансировка нагрузки — upstream блоки и методы распределения
- SSL/TLS — настройка HTTPS и редиректы
- Оптимизация — gzip, кэширование, буферы и таймауты
- Безопасность — security headers и rate limiting
- PHP-FPM — интеграция с PHP приложениями
- Логирование — форматы логов и пользовательские настройки
Понимание того, как работает каждая директива и почему она настроена определенным образом, поможет вам создавать эффективные, безопасные и высокопроизводительные конфигурации Nginx для любых задач.