Nginx - это высокопроизводительный веб-сервер и обратный прокси, который стал стандартом для современных веб-приложений. Его событийно-ориентированная архитектура эффективно обрабатывает тысячи одновременных соединений с минимальным потреблением памяти. Виртуальные хосты (server блоки) - это фундаментальный механизм Nginx для размещения нескольких независимых сайтов или приложений на одном сервере. Это руководство предоставляет полный набор проверенных на практике конфигураций, от базового статического сайта до сложных сценариев с балансировкой нагрузки. Все примеры актуальны для 2026 года и готовы к применению в рабочей среде Ubuntu/Debian.
Базовый каркас: структура конфигов и ваш первый виртуальный хост
После установки Nginx из официальных репозиториев система конфигурации организуется вокруг нескольких ключевых директорий и файлов. Основной конфигурационный файл /etc/nginx/nginx.conf включает в себя глобальные настройки. Для управления сайтами используются директории /etc/nginx/sites-available/ (здесь хранятся все конфигурации) и /etc/nginx/sites-enabled/ (сюда добавляются символические ссылки на активные конфигурации). Эта структура позволяет легко включать и отключать сайты без удаления их конфигурационных файлов.
Готовая конфигурация виртуального хоста (с комментариями)
Создайте файл конфигурации для вашего первого сайта, например, /etc/nginx/sites-available/my-site.conf. Вот минимальный рабочий шаблон для статического сайта с подробными комментариями.
server {
# Сервер слушает входящие HTTP-запросы на порту 80 для всех сетевых интерфейсов.
listen 80;
# Указываем доменное имя, для которого работает этот server блок.
# Можно перечислить несколько имен через пробел: server_name example.com www.example.com;
server_name my-site.local;
# Корневая директория, откуда Nginx будет отдавать файлы сайта.
# Убедитесь, что у пользователя, от имени которого работает Nginx (обычно www-data или nginx),
# есть права на чтение файлов в этой директории.
root /var/www/my-site/html;
# Список индексных файлов, которые Nginx будет искать при обращении к директории.
index index.html index.htm;
# Блок location для обработки всех запросов ( / ).
location / {
# Пытается найти запрошенный URI как файл, затем как директорию,
# и если ничего не найдено, отдает индексный файл.
try_files $uri $uri/ =404;
}
# Блок для логирования. Рекомендуется настраивать отдельные логи для каждого сайта.
access_log /var/log/nginx/my-site.access.log;
error_log /var/log/nginx/my-site.error.log;
}
После создания файла активируйте сайт, создав символическую ссылку, и проверьте синтаксис конфигурации.
sudo ln -s /etc/nginx/sites-available/my-site.conf /etc/nginx/sites-enabled/
sudo nginx -t # Проверка синтаксиса
sudo systemctl reload nginx # Применение конфигурации без простоя
Разграничение окружений: разработка (dev) vs продакшен (prod)
Для предотвращения ошибок при переносе настроек между средами используйте отдельные конфигурационные файлы или управляйте параметрами через переменные окружения. Простой подход - создание шаблонных конфигураций с последующим включением окружения.
1. Создайте базовый конфиг /etc/nginx/sites-available/my-site-base.conf:
server {
listen 80;
server_name my-site.local;
root /var/www/my-site/html;
index index.html;
# Включаем файл с настройками окружения
include /etc/nginx/conf.d/my-site-environment.conf;
location / {
try_files $uri $uri/ =404;
}
}
2. Создайте конфигурацию для разработки /etc/nginx/conf.d/my-site-dev.conf:
# Dev-окружение: отладочный режим, отключенное кэширование для разработчика.
client_max_body_size 50M; # Разрешаем загрузку больших файлов
# Отключаем кэширование статики в браузере для удобства разработки
add_header Cache-Control "no-cache, no-store, must-revalidate";
# Включаем подробное логирование
access_log /var/log/nginx/my-site-dev.access.log;
3. Создайте конфигурацию для продакшена /etc/nginx/conf.d/my-site-prod.conf:
# Prod-окружение: безопасность и производительность.
# Включаем кэширование статики на 30 дней
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# Базовые заголовки безопасности
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# Ограничиваем размер тела запроса
client_max_body_size 10M;
Символическую ссылку для my-site-environment.conf можно менять в зависимости от среды, используя скрипты развертывания (CI/CD). Для более комплексного подхода к настройке продакшн-окружения изучите полное руководство по настройке Nginx для production-среды.
Обработка динамического контента: интеграция с бэкендами
Nginx сам не выполняет код PHP, Python или JavaScript. Его роль - принимать запросы от клиентов и передавать их специализированным процессам бэкенда по протоколам FastCGI или HTTP (проксирование). Это разделение обязанностей повышает безопасность и производительность.
Оптимальная конфигурация для PHP-FPM
Для работы с PHP используется менеджер процессов PHP-FPM. Nginx передает запросы к .php файлам через протокол FastCGI. Вот стандартный и надежный блок location для обработки PHP.
server {
... # Базовые настройки server_name, root и т.д.
location ~ \.php$ {
# Пытаемся найти и передать скрипт. Если файл не существует - 404.
try_files $uri =404;
# Разделитель для FastCGI. В конце должен быть /, даже если путь пустой.
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Защита от попыток выполнения произвольного кода.
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Указываем, куда передавать запрос. Можно использовать сокет или TCP.
# Сокет (рекомендуется для одного сервера):
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
# TCP (подходит для распределенных систем):
# fastcgi_pass 127.0.0.1:9000;
# Включаем стандартные параметры FastCGI
include fastcgi_params;
# Устанавливаем таймауты для предотвращения 502 ошибок при долгих запросах.
fastcgi_read_timeout 60;
fastcgi_send_timeout 60;
}
# Важно: запрещаем прямой доступ к другим .php файлам, например, конфигурационным.
location ~ /(config|system|vendor)/.*\.php$ {
deny all;
return 403;
}
}
Убедитесь, что пользователь www-data (или nginx) имеет права на чтение сокета PHP-FPM. Обычно это регулируется параметром listen.owner и listen.group в конфигурационном файле пула PHP-FPM (например, /etc/php/8.3/fpm/pool.d/www.conf).
Проксирование к Node.js и Python приложениям
Приложения на Node.js (Express, Nest.js) или Python (Django, Flask, FastAPI) часто запускаются как отдельные сервисы, слушающие localhost на определенном порту (например, 3000 или 8000). Nginx выступает в роли обратного прокси, перенаправляя запросы клиентов к этим сервисам.
Конфигурация для Node.js приложения (localhost:3000):
server {
listen 80;
server_name api.my-site.local;
location / {
# Адрес бэкенд-приложения.
proxy_pass http://127.0.0.1:3000;
# Критически важно передавать оригинальные заголовки, особенно Host.
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;
# Таймауты для долгих операций (загрузка файлов, long polling).
proxy_connect_timeout 75s;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
}
# Поддержка WebSocket соединений (для реального времени, чатов).
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
Конфигурация для Python приложения (Gunicorn/Uvicorn на сокете):
server {
listen 80;
server_name app.my-site.local;
location / {
# Проксирование на Unix-сокет, который создает Gunicorn/Uvicorn.
proxy_pass http://unix:/run/gunicorn/myapp.sock;
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;
}
# Статические файлы Django/Flask лучше отдавать напрямую через Nginx.
location /static/ {
alias /var/www/myapp/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /var/www/myapp/media/;
expires 7d;
add_header Cache-Control "public";
}
}
Для получения большего количества готовых шаблонов конфигураций, включая сложные сценарии с Docker, обратитесь к нашей коллекции практических шаблонов Nginx.
Безопасность: контроль доступа, SSL/TLS и защита от атак
Базовая безопасность виртуального хоста включает обязательное использование HTTPS, контроль доступа к чувствительным разделам и защиту от распространенных векторов атак. Эти меры должны применяться ко всем production-окружениям.
Автоматическое получение и обновление SSL-сертификатов Let's Encrypt
Certbot - стандартный инструмент для автоматизации работы с Let's Encrypt. Установите его и настройте для Nginx.
sudo apt update
sudo apt install certbot python3-certbot-nginx
# Получение сертификата для домена с автоматической настройкой Nginx
sudo certbot --nginx -d my-site.local -d www.my-site.local
Certbot автоматически изменит конфигурацию вашего виртуального хоста, добавив блок listen 443 ssl и необходимые директивы для SSL. Он также настроит автоматическое обновление сертификатов через системный таймер. В конфигурации появится редирект с HTTP на HTTPS.
server {
listen 80;
server_name my-site.local www.my-site.local;
# Принудительный редирект всех HTTP-запросов на HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2; # HTTP/2 работает только поверх HTTPS
server_name my-site.local www.my-site.local;
# Пути к сертификатам, сгенерированные Certbot
ssl_certificate /etc/letsencrypt/live/my-site.local/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-site.local/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
... # остальная конфигурация сайта
}
Блокировка и разрешение доступа по IP-адресам
Используйте директивы allow и deny внутри блоков location для ограничения доступа к административным интерфейсам или staging-окружениям.
# Разрешаем доступ к панели администратора только с офисного IP и localhost.
location /admin/ {
allow 192.168.1.0/24; # Локальная сеть
allow 203.0.113.5; # Конкретный публичный IP
allow 127.0.0.1; # Localhost
deny all; # Запрет для всех остальных
... # proxy_pass или fastcgi_pass для бэкенда
}
# Защита WordPress wp-admin (в дополнение к сильным паролям).
location ~* ^/wp-admin/ {
allow 192.168.1.0/24;
deny all;
try_files $uri $uri/ /index.php$is_args$args;
}
# Защита API-эндпоинта от публичного доступа.
location /api/v1/internal/ {
allow 10.0.0.0/8; # Разрешаем только из внутренней сети
deny all;
return 403;
}
Важно: этот метод неэффективен для пользователей с динамическими IP-адресами или при использовании CDN. В таких случаях необходима аутентификация на уровне приложения или с помощью базовой аутентификации Nginx (auth_basic).
Оптимизация производительности и удобства
Правильная настройка кэширования и сжатия может в разы увеличить скорость отдачи контента и снизить нагрузку на сервер и канал связи. Эти оптимизации особенно важны для сайтов со статическим контентом и API с повторяющимися ответами.
Сжатие контента и кеширование (gzip, brotli, proxy_cache)
Сжатие Gzip и Brotli: Brotli обеспечивает лучшее сжатие, чем gzip, особенно для текстовых ресурсов. Настройте оба алгоритма.
# В контексте http (внутри nginx.conf или отдельного include-файла)
gzip on;
gzip_vary on;
gzip_min_length 1024; # Сжимаем файлы больше 1 КБ
# Типы файлов для сжатия
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
# Уровень сжатия gzip (1-9). 6 - оптимальный баланс скорости и степени сжатия.
gzip_comp_level 6;
# Brotli сжатие (требует отдельной сборки Nginx с модулем или установки пакета nginx-extras).
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
Кэширование статики в браузере: Укажите браузеру кэшировать статические ресурсы на длительный срок.
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
location ~* \.(css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
Кэширование прокси (proxy_cache): Кэширует ответы от бэкенда (например, от API или CMS) непосредственно на диске Nginx.
# Определяем зону кэша в контексте http.
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
...
location /api/ {
proxy_pass http://backend;
# Включаем кэш для этого location.
proxy_cache my_cache;
# Ключ кэша: по умолчанию $scheme$proxy_host$request_uri.
proxy_cache_key "$host$request_uri$cookie_user";
# Кэшируем ответы с кодом 200 на 10 минут.
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
# Добавляем заголовок в ответ, чтобы видеть, попал ли ответ из кэша (HIT/MISS/BYPASS).
add_header X-Cache-Status $upstream_cache_status;
}
}
Чистые URL и перенаправления
Директива rewrite изменяет URI запроса внутри Nginx. Используйте ее осторожно, так как избыточные rewrite-правила усложняют отладку.
# Убираем расширение .php из URL (пример для PHP-сайта).
# Запрос /about будет внутренне обработан как /about.php
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/(.*)$ /$1.php last;
}
# Редирект с www на non-www (или наоборот). Делается на уровне server блока.
server {
listen 80;
server_name www.my-site.local;
return 301 $scheme://my-site.local$request_uri;
}
# Постоянный редирект (301) при переезде страницы.
location = /old-page.html {
return 301 /new-page;
}
# Редирект всех запросов со старого домена на новый.
server {
listen 80;
server_name old-domain.local;
return 301 https://new-domain.local$request_uri;
}
Для глубокого понимания всех возможностей структуры конфигурации Nginx и тонкой настройки параметров performance ознакомьтесь с полным разбором структуры nginx.conf.
Логирование и диагностика для каждого виртуального хоста
Настройка отдельных логов для каждого сайта - обязательная практика. Это позволяет быстро изолировать проблему, не фильтруя общий файл /var/log/nginx/access.log.
Настройка отдельных логов и их анализ
Укажите пути к лог-файлам внутри каждого server блока.
server {
server_name my-site.local;
# Лог доступа в формате combined с буферизацией (32k буфер, сброс при заполнении).
access_log /var/log/nginx/my-site.access.log combined buffer=32k flush=5m;
# Лог ошибок с уровнем предупреждений warn.
error_log /var/log/nginx/my-site.error.log warn;
...
}
Анализ error.log:
connect() failed (111: Connection refused)- Nginx не может подключиться к бэкенду (PHP-FPM, Node.js). Проверьте, запущен ли сервис бэкенда.primary script unknown- Ошибка в директивеfastcgi_param SCRIPT_FILENAME. Убедитесь, что путь к файлу корректен.open() "/var/www/..." failed (13: Permission denied)- Проблема с правами доступа к файлам сайта.no live upstreams while connecting to upstream- Все серверы в блокеupstreamотмечены как нерабочие.
Базовая статистика (stub_status): Включите модуль для мониторинга базовых метрик. Добавьте в конфигурацию:
location /nginx_status {
stub_status;
# Обязательно ограничьте доступ к этой статистике!
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
Запрос к http://my-site.local/nginx_status вернет данные в формате:
Active connections: 3
server accepts handled requests
100 100 200
Reading: 0 Writing: 1 Waiting: 2
Ротация логов: Пакет logrotate обычно уже настроен для Nginx. Конфигурация находится в /etc/logrotate.d/nginx. Она обеспечивает ежедневный ротат логов, их сжатие и удаление старых файлов.
Продвинутые сценарии и лучшие практики
Для сложных проектов с высокими требованиями к доступности и производительности Nginx предоставляет инструменты для балансировки нагрузки, гибкой маршрутизации и автоматизации управления конфигурациями.
Балансировка нагрузки и отказоустойчивость (upstream)
Блок upstream определяет группу серверов бэкенда, между которыми Nginx распределяет запросы.
# Определяем группу бэкендов для нашего приложения.
upstream backend_cluster {
# Балансировка по умолчанию - round-robin.
# least_conn; # Можно раскомментировать для балансировки по наименьшему числу соединений.
server 10.0.1.10:3000 weight=3; # У этого сервера в 3 раза больше «веса»
server 10.0.1.11:3000;
server 10.0.1.12:3000 backup; # Резервный сервер, используется, если оба основных недоступны.
# Пассивные health checks: сервер временно исключается после ошибок соединения/таймаута.
}
server {
location / {
proxy_pass http://backend_cluster;
# Активные health checks (требуют отдельного коммерческого модуля или Nginx Plus).
# health_check interval=5s fails=3 passes=2;
}
}
При падении одного из серверов Nginx автоматически перенаправит трафик на остальные рабочие инстансы. Для реализации сложных сценариев высокой доступности, включая активные health checks и graceful shutdown, изучите продвинутое руководство по настройке Nginx как балансировщика нагрузки.
Резервное копирование и управление конфигами
Конфигурации Nginx - это инфраструктурный код. Относитесь к ним соответственно: храните в Git, проводите code review, используйте CI/CD для развертывания.
Скрипт для быстрого бэкапа конфигов:
#!/bin/bash
BACKUP_DIR="/backup/nginx/$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
cp -r /etc/nginx $BACKUP_DIR/
# Также можно архивировать логи на момент бэкапа
tar -czf $BACKUP_DIR/nginx_backup.tar.gz /etc/nginx
find /backup/nginx -type d -mtime +30 -exec rm -rf {} \; # Удаляем бэкапы старше 30 дней
Использование Git: Инициализируйте репозиторий в /etc/nginx/ (или в отдельной директории с вашими конфигами из sites-available). Добавьте .gitignore, чтобы не отслеживать симлинки из sites-enabled, сертификаты Let's Encrypt и временные файлы. Это позволяет отслеживать изменения, откатываться к предыдущим версиям и автоматически развертывать конфигурации на несколько серверов.
Для сравнения архитектурных решений и выбора оптимального веб-сервера под конкретный проект рекомендуем ознакомиться с практическим сравнением Nginx и Apache в 2026 году.
Эффективная работа с современными технологиями часто требует интеграции с инструментами искусственного интеллекта для автоматизации рутинных задач, анализа логов или генерации кода. Для удобного и безопасного доступа к множеству AI-моделей через единый API, оплачиваемый в рублях, вы можете рассмотреть сервис AiTunnel. Он агрегирует более 200 моделей, включая GPT, Gemini и Claude, и позволяет управлять бюджетами и ключами в одном интерфейсе.