Полное руководство по виртуальным хостам Nginx: от первого сайта до продвинутой оптимизации (2026) | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Полное руководство по виртуальным хостам Nginx: от первого сайта до продвинутой оптимизации (2026)

04 мая 2026 13 мин. чтения
Содержание статьи

Вы хотите разместить несколько сайтов на одном сервере, настроить PHP, Node.js или Python приложение, защитить его SSL/TLS и оптимизировать производительность. Виртуальные хосты Nginx — это фундаментальный механизм для решения этих задач. Это руководство предоставляет полный набор проверенных на практике конфигураций, от базового статического сайта до сложных сценариев с балансировкой нагрузки. Все примеры актуальны для 2026 года и готовы к применению в рабочей среде Ubuntu/Debian.

Оглавление и уровни сложности

  • Базовый каркас: для тех, кто создает первый виртуальный хост. Структура конфигов и готовый шаблон.
  • Обработка динамического контента: для интеграции с PHP-FPM, Node.js и Python бэкендами.
  • Безопасность: обязательные меры — SSL/TLS, контроль доступа по IP, защита от атак.
  • Оптимизация производительности: кэширование, сжатие (gzip, brotli), чистые URL для увеличения скорости.
  • Логирование и диагностика: настройка отдельных логов и анализ типовых ошибок для каждого хоста.
  • Продвинутые сценарии: для высоконагруженных проектов — балансировка нагрузки (upstream), резервное копирование конфигов.

Базовый каркас: структура конфигов и ваш первый виртуальный хост

После установки 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;
}

4 шага для активации вашего первого виртуального хоста:

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 (проксирование). Это разделение обязанностей повышает безопасность и производительность.

Бэкенд Протокол Типичный порт/сокет Пример use-case
PHP (PHP-FPM) FastCGI Unix сокет (рекомендуется) WordPress, Laravel, традиционные CMS
Node.js HTTP проксирование TCP порт (e.g., 3000) API (Express, Nest.js), приложения реального времени
Python (Gunicorn/Uvicorn) HTTP проксирование Unix сокет или TCP порт Django, Flask, FastAPI, микросервисы

Оптимальная конфигурация для 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/TLS и автоматическое обновление сертификатов 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).

Чек-лист безопасности для виртуального хоста:

  • SSL/TLS настроен и работает (HTTPS)?
  • Редирект с HTTP на HTTPS включен?
  • Доступ к административным интерфейсам ограничен по IP или аутентификации?
  • Для сайта настроены отдельные логи (access_log, error_log)?
  • Базовые заголовки безопасности (X-Frame-Options, X-Content-Type-Options) добавлены?

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

Правильная настройка кэширования и сжатия может в разы увеличить скорость отдачи контента и снизить нагрузку на сервер и канал связи. Эти оптимизации особенно важны для сайтов со статическим контентом и 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, и позволяет управлять бюджетами и ключами в одном интерфейсе.

Поделиться:
Сохранить гайд? В закладки браузера