Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Системное Администрирование
  4. nginx
  5. Исчерпывающее руководство по конфигурации Nginx

Исчерпывающее руководство по конфигурации Nginx

Запланировано Прикреплена Закрыта Перенесена nginx
1 Сообщения 1 Постеры 57 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • MugiwaraM Не в сети
    MugiwaraM Не в сети
    Mugiwara
    написал в отредактировано Aladdin
    #1

    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-блок:

    1. Точное совпадение имени
    2. Самое длинное совпадение, начинающееся с *
    3. Самое длинное совпадение, заканчивающееся на *
    4. Первое совпадение по регулярному выражению
    5. Default server (указанный с default_server в listen)

    Директива Location

    Location-блоки определяют, как обрабатывать запросы в зависимости от URI.

    Синтаксис и модификаторы

    location [modifier] path {
        # конфигурация
    }
    

    Модификаторы:

    • = — точное совпадение (наивысший приоритет)
    • ^~ — преимущественное префиксное совпадение (останавливает поиск regex)
    • ~ — regex с учетом регистра
    • ~* — regex без учета регистра
    • (без модификатора) — префиксное совпадение

    Порядок приоритета location

    1. Точные совпадения =
    2. Преимущественные префиксы ^~
    3. Регулярные выражения ~ и ~* (в порядке появления в файле)
    4. Префиксные совпадения (самый длинный префикс имеет приоритет)

    Примеры 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;
    }
    

    Как это работает:

    1. Сначала проверяет, существует ли файл $uri
    2. Если нет, проверяет, является ли $uri/ директорией
    3. Если нет, отдает /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 для любых задач.

    1 ответ Последний ответ
    4

    Категории

    • Главная
    • Новости
    • Фронтенд
    • Бекенд
    • Языки программирования

    Контакты

    • Сотрудничество
    • info@exlends.com
    • Наш чат
    • Наш ТГ канал

    © 2024 - 2025 ExLends, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы