Виртуальные хосты в Nginx: 7 ошибок новичков
Один Nginx может обслуживать несколько сайтов, но ошибка в listen, server_name или DNS отправит запрос не тому проекту. Разбираем конфигурацию виртуальных хостов на Nginx 1.26.x и проверяем её без догадок.

Один сервер Nginx может отдавать несколько сайтов с одного IP-адреса, но неверный server_name отправит посетителя в чужой каталог, а второй default_server не даст Nginx перезапуститься. Ниже — практический разбор для Nginx 1.26.x: как устроить отдельные конфигурации, какие ошибки чаще всего делают новички и чем проверять результат до перезагрузки сервера.
Как Nginx выбирает виртуальный хост
Для каждого HTTP-запроса Nginx сначала смотрит на IP-адрес и порт из директивы listen, а затем сравнивает имя из заголовка Host с директивами server_name. Если совпадения нет, запрос попадает в сервер, помеченный как default_server. Если такой пометки нет, используется первый подходящий блок для этого адреса и порта.
Именно поэтому открытие сайта по IP не проверяет настройку домена полностью: в запросе нет нужного имени хоста, и Nginx может закономерно показать стандартную страницу или другой проект.
Сноска. Виртуальный хост — отдельный блок server, который описывает сайт или приложение: его доменные имена, порт, каталог файлов и правила обработки запросов.
Главное правило диагностики: сначала проверьте, какой запрос реально отправляет браузер, затем — какой блок
serverможет его принять. Не начинайте с бесконечного редактированияroot.
Базовая схема для двух сайтов
В конфигурации удобно держать отдельный файл для каждого домена. На Debian и Ubuntu часто используют каталоги /etc/nginx/sites-available и /etc/nginx/sites-enabled, но это не универсальное требование Nginx: конкретная схема зависит от главного файла и строк include.
Сначала убедитесь, что главный конфигурационный файл подключает нужный каталог. Выполните:
sudo nginx -t
sudo nginx -T
Команда nginx -t проверяет синтаксис и доступность файлов, а nginx -T выводит итоговую конфигурацию вместе с подключёнными файлами. В выводе второй команды должны быть оба блока server.
Сайт со статическими файлами
Пример для домена example.ru. Директива root указывает каталог, в котором Nginx ищет файл, совпадающий с URL запроса.
server {
listen 80;
listen [::]:80;
server_name example.ru www.example.ru;
root /var/www/example.ru/public;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
После создания каталога и файла index.html проверка проста: запрос к http://example.ru/ должен вернуть содержимое этого файла. Если отображается другой сайт, проблема обычно в DNS, server_name или порядке выбора серверного блока, а не в HTML.
Сайт за приложением
Для приложения, которое слушает локальный порт, Nginx выступает обратным прокси. Само приложение должно уже работать, например на 127.0.0.1:8000.
server {
listen 80;
listen [::]:80;
server_name app.example.ru;
location / {
proxy_pass http://127.0.0.1:8000;
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;
}
}
Проверка результата: приложение должно отвечать через http://app.example.ru/, а запрос к http://127.0.0.1:8000/ на сервере должен подтверждать, что backend действительно запущен. Если локальный порт закрыт, Nginx не сможет исправить это настройкой виртуального хоста.
Семь ошибок, которые ломают настройку
1. Домен не указывает на этот сервер
Файл Nginx может быть идеальным, но DNS всё равно отправляет посетителя на старый хостинг. Проверьте A-запись домена и, если используется IPv6, AAAA-запись. Если AAAA ведёт на другой сервер, часть клиентов будет попадать не туда, даже когда IPv4 настроен правильно.
Проверяйте результат с той сети, где возникает проблема. DNS-кеш может сохранять старый ответ дольше, чем ожидается по TTL. Сам Nginx DNS-запись домена не меняет.
2. В server_name указано имя с протоколом
В этой директиве не пишут https:// и путь. Правильно: server_name example.ru www.example.ru;. Вариант server_name https://example.ru; не соответствует обычному значению заголовка Host и не выбирает сайт так, как ожидает новичок.
3. Запрос идёт на IP, а не на домен
При открытии IP-адреса браузер отправляет другой заголовок Host. Nginx выбирает сервер по этому значению, поэтому вы можете увидеть страницу default_server. Это не доказывает, что домен настроен неправильно.
Для проверки используйте доменное имя. Если DNS ещё не обновился, можно временно проверить маршрутизацию через локальный файл hosts, но не оставляйте такую запись как постоянное решение для пользователей.
4. Перепутаны root и alias
Для обычного сайта чаще нужен root: Nginx добавляет URI к указанному каталогу. alias заменяет соответствующую часть пути и особенно чувствителен к завершающему слешу. Смешивание этих директив в соседних location часто даёт неожиданный путь к файлу.
Если запрос к /assets/app.css возвращает 404, сначала вычислите фактический путь на диске, а затем сравните его с правилами location. Не меняйте права доступа на весь сервер наугад.
5. Файл создан, но не подключён
Наличие файла в sites-available ещё не означает, что Nginx его читает. Проверьте строку include в основной конфигурации и итоговый вывод nginx -T. На системах с символическими ссылками дополнительно проверьте, что ссылка ведёт к существующему файлу.
После изменения конфигурации применяйте её только после проверки:
sudo nginx -t
sudo systemctl reload nginx
Перезагрузка перечитывает конфигурацию без остановки уже обслуживаемых соединений, но команда сработает только при корректной структуре службы в вашей системе.
6. Два блока объявлены как default_server
Для одного адреса и порта должен быть один сервер по умолчанию. При дублировании Nginx обычно завершает проверку сообщением вроде duplicate default server for 0.0.0.0:80. Уберите флаг из лишнего блока или назначьте отдельный IP-адрес, если действительно нужна другая схема.
7. Приложение слушает не тот адрес или порт
В прокси-конфигурации легко указать 127.0.0.1:8000, когда приложение работает на другом порту, либо наоборот. В результате браузер получает ответ 502 Bad Gateway. Проверьте журнал Nginx и состояние самого приложения. Ошибка 502 означает, что цепочка до backend не завершилась, а не то, что сломан server_name.
Какие варианты конфигурации выбрать
Новичкам обычно не нужна сложная система шаблонов. Важнее отделить сайты друг от друга и сделать очевидным, какой блок отвечает за какой домен.
| Схема | Когда использовать | Цена и риск |
|---|---|---|
Отдельный server на домен | Для двух и более независимых сайтов | Больше файлов, зато проще искать ошибку и ограничивать изменения |
| Один блок с несколькими именами | Для домена и его алиаса, например с www | Удобно, но все имена получают одинаковые правила и каталог |
Wildcard в server_name | Для предсказуемых поддоменов вроде *.example.ru | Можно случайно принять неизвестный поддомен и отправить его не в тот проект |
Отдельный default_server | Для неизвестных доменов и запросов по IP | Нужен отдельный ответ, иначе посетитель увидит первый сайт |
Когда что выбирать
Объединяйте имена в один блок только тогда, когда у них одинаковые каталог, HTTPS-настройки и логика приложения. Если для www нужен редирект на основной домен, лучше выделить отдельный блок или отдельное правило, чтобы поведение было явным.
Wildcard оправдан, когда поддомены создаются по одной схеме и вы контролируете их список. Для нескольких несвязанных проектов используйте отдельные блоки. Так вы не получите ситуацию, когда новый домен случайно начинает отдавать файлы старого магазина.
Проверка перед публикацией
- Проверьте A- и AAAA-записи домена. Они должны указывать на сервер, где работает Nginx.
- Убедитесь, что в
server_nameуказаны только нужные имена без протокола и пути. - Проверьте, что каталог из
rootсуществует, а внутри есть ожидаемый файл. - Для прокси проверьте доступность backend на указанном локальном адресе и порте.
- Запустите
sudo nginx -t. При ошибке не выполняйте reload, пока не исправите указанную строку. - Посмотрите итоговую конфигурацию через
sudo nginx -Tи убедитесь, что нужный файл действительно подключён. - Проверьте домен по HTTP, а затем отдельно настройте HTTPS и редирект. TLS не исправляет неверный выбор виртуального хоста.
Что делать, если не получилось
- Показывается другой сайт. Проверьте заголовок
Host, DNS, точное написание домена и наличие лишнегоdefault_server. - Ответ 404. Сверьте URL с фактическим путём, директивы
rootиtry_files, а также права чтения каталога. - Ответ 502 Bad Gateway. Проверьте порт приложения, его состояние и адрес, на котором оно слушает.
- Сообщение
server directive is not allowed here. Блокserverразмещён вне контекстаhttpили подключён не в том месте. - Сообщение о duplicate default server. Оставьте только один
default_serverдля конкретной пары IP и порта.
Что проверить дальше
После базовой маршрутизации включите раздельные access-логи для сайтов и проверьте, какой домен, URI и код ответа реально приходят в Nginx. Затем настройте HTTPS, редирект с HTTP и резервную копию конфигурации. В проде особенно полезно следить за долей ответов 4xx и 5xx: рост 404 укажет на маршрутизацию или пути к файлам, а рост 502 — на состояние приложения и связь с backend.
Логотип и фирменный стиль: Три концепции разного характера, палитра с обоснованием, проверка на читаемость в малом размере и в один цвет.
Спросить за 60 ₽Источники: Nginx Documentation: How nginx processes a request, Nginx Documentation: Core functionality
Частые вопросы
Почему при открытии домена я вижу стандартную страницу Nginx?
Можно ли указать несколько доменов в одном server_name?
Что делать, если после изменения конфигурации nginx не перезапускается?
Грозит ли ошибка виртуального хоста простоем сайта?
Почему Nginx возвращает 502, хотя server_name указан правильно?
Нужно ли отдельно настраивать IPv6?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.