Nginx Server Blocks: несколько сайтов на одном VPS
Server block в Nginx — это блок конфигурации server { }, который позволяет разместить несколько сайтов на одном сервере: каждый блок описывает свой домен, папку с файлами и настройки SSL. Один Nginx может обслуживать сколько угодно server blocks одновременно — он смотрит на заголовок Host во входящем запросе и направляет его в нужный блок. Так десятки сайтов работают на одном VPS с одним IP-адресом, разделяясь только по доменному имени.
Как Nginx выбирает нужный сайт
Когда браузер запрашивает сайт, он отправляет заголовок Host со значением домена. Nginx сравнивает это значение с директивой server_name в каждом server block и передаёт запрос в тот блок, где есть совпадение.
Порядок проверки совпадений фиксированный:
Nginx сначала ищет точное совпадение домена — например, example.com совпадёт только с server_name example.com;.
Если точного совпадения нет, в ход идут wildcard-домены со звёздочкой в начале, вида *.example.com — такой шаблон совпадёт с blog.example.com или shop.example.com.
Следующими проверяются wildcard-домены со звёздочкой в конце, вида www.example.*.
Регулярные выражения в server_name, если они использовались, проверяются в последнюю очередь. Побеждает первое найденное совпадение по этому порядку — на этом поиск прекращается.
Структура файлов конфигурации
Стандартная структура Nginx на Ubuntu разделяет конфигурацию на две директории.
Директория /etc/nginx/sites-available/ хранит конфигурационные файлы всех сайтов — и активных, и неактивных. Это просто место хранения, само по себе оно ни на что не влияет.
Директория /etc/nginx/sites-enabled/ содержит символические ссылки на те файлы из sites-available, которые должны быть активны. Именно наличие ссылки в этой директории делает сайт видимым для Nginx.
Такое разделение удобно на практике: чтобы временно отключить сайт не удаляя его конфигурацию, достаточно удалить ссылку из sites-enabled, оставив сам файл в sites-available.
Nginx несколько сайтов: создание server block
Создать директорию для файлов первого сайта:
sudo mkdir -p /var/www/site1.com/html
Создать директорию для файлов второго сайта:
sudo mkdir -p /var/www/site2.com/html
Создать тестовую страницу для проверки, что каждый сайт открывает правильный контент:
echo "<h1>Сайт 1: site1.com</h1>" | sudo tee /var/www/site1.com/html/index.html
echo "<h1>Сайт 2: site2.com</h1>" | sudo tee /var/www/site2.com/html/index.html
Создать конфигурационный файл для первого сайта:
sudo nano /etc/nginx/sites-available/site1.com
Содержимое файла для первого сайта:
server {
listen 80;
listen [::]:80;
server_name site1.com www.site1.com;
root /var/www/site1.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Создать конфигурационный файл для второго сайта:
sudo nano /etc/nginx/sites-available/site2.com
Содержимое файла для второго сайта — структура идентична, отличаются только домен и путь:
server {
listen 80;
listen [::]:80;
server_name site2.com www.site2.com;
root /var/www/site2.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Активировать оба сайта, создав символические ссылки:
sudo ln -s /etc/nginx/sites-available/site1.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.com /etc/nginx/sites-enabled/
Проверить конфигурацию на синтаксические ошибки перед применением:
sudo nginx -t
Если проверка прошла без ошибок, применить изменения:
sudo systemctl reload nginx
default_server: что происходит с незнакомыми доменами
Если на сервер приходит запрос с доменом или IP-адресом, который не совпадает ни с одним server_name, Nginx должен как-то на него отреагировать. По умолчанию он выбирает для этого первый попавшийся server block в порядке чтения файлов — то есть неочевидным и не всегда предсказуемым образом.
Чтобы явно контролировать это поведение, один из блоков нужно пометить флагом default_server:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
Значение server_name _; означает «любое имя, которое не совпало ни с чем другим». Директива return 444; — это специальный код Nginx, который обрывает соединение без ответа. Такой блок работает как заглушка для ботов и сканеров, которые обращаются к серверу напрямую по IP, а не по доменному имени — они получают разрыв соединения вместо реального сайта.
Разместите этот блок в отдельном файле и подключите его первым в списке sites-enabled, чтобы не возникало путаницы с тем, какой из ваших настоящих сайтов случайно станет дефолтным.
Настройка SSL для нескольких сайтов
Каждый домен на сервере получает собственный SSL-сертификат. Это не создаёт конфликтов, потому что современные браузеры поддерживают технологию SNI (Server Name Indication) — клиент сообщает серверу нужный домен ещё до завершения установки защищённого соединения, и Nginx на основе этой информации выбирает правильный сертификат из нескольких доступных на одном IP и порту 443.
Выпустить сертификат для первого сайта через Certbot:
sudo certbot --nginx -d site1.com -d www.site1.com
Выпустить сертификат для второго сайта:
sudo certbot --nginx -d site2.com -d www.site2.com
Certbot автоматически найдёт нужный server block по указанному домену и добавит в него директивы ssl_certificate вместе с настройкой автоматического редиректа с HTTP на HTTPS. Ручное редактирование конфигурационных файлов после этого не требуется.
Раздельные логи для каждого сайта
Если несколько сайтов пишут логи в общий файл, диагностировать проблему конкретного сайта становится неудобно — приходится вручную выискивать нужные строки среди чужого трафика. Чтобы у каждого сайта были собственные файлы логов, добавьте директивы внутри соответствующего server block:
server {
listen 80;
server_name site1.com www.site1.com;
root /var/www/site1.com/html;
access_log /var/log/nginx/site1.com-access.log;
error_log /var/log/nginx/site1.com-error.log;
location / {
try_files $uri $uri/ =404;
}
}
После этого изменения все запросы и ошибки конкретного сайта будут записываться в отдельные файлы, и отследить проблему одного сайта не потребует просмотра логов всех остальных.
Проверка какой сайт отвечает без настройки DNS
Часто нужно протестировать маршрутизацию по доменам ещё до того, как DNS-записи для нового домена реально настроены и распространились. Сделать это можно, подменив заголовок Host в запросе вручную:
curl -H "Host: site1.com" http://ВАШ_IP/
Такой запрос обратится напрямую по IP-адресу сервера, но с заголовком Host, как будто пришёл с настоящего домена site1.com. Nginx обработает его так же, как обычный запрос от этого домена, и вернёт содержимое соответствующего сайта — это позволяет проверить правильность конфигурации до того, как домен будет привязан к серверу через DNS.
Nginx несколько сайтов на разных IP-адресах
Если на сервере доступно несколько IP-адресов, сайты можно разделить не только по домену, но и по конкретному IP, указав его явно в директиве listen:
server {
listen 192.168.1.10:80;
server_name site1.com;
root /var/www/site1.com/html;
}
server {
listen 192.168.1.11:80;
server_name site2.com;
root /var/www/site2.com/html;
}
Директива listen 80; без указания адреса заставляет Nginx слушать этот порт на всех IP-адресах сервера сразу. Указание конкретного IP в listen сужает область действия блока до этого единственного адреса — это может пригодиться, например, если разные сайты должны быть физически изолированы на сетевом уровне.
Поиск конфликтов между конфигурациями
Если несколько файлов конфигурации случайно содержат одинаковый server_name, Nginx применит только первый найденный по порядку блок, а остальные с тем же именем будут молча проигнорированы — без явной ошибки, что затрудняет диагностику.
Чтобы увидеть полную объединённую конфигурацию Nginx со всеми загруженными файлами, выполните:
sudo nginx -T
Команда выводит содержимое главного конфигурационного файла вместе со всеми подключёнными через include, что позволяет визуально найти дублирующиеся server_name между разными файлами в sites-enabled.
Частые ошибки
Директива root не указана нигде в блоке
Если директива root отсутствует и в самом server block, и в его location-блоках, Nginx использует путь по умолчанию — обычно это /usr/share/nginx/html или аналогичная системная директория, в зависимости от дистрибутива. Сайт при этом откроется, но покажет совсем не тот контент, который ожидался.
Один и тот же server_name в разных файлах
Если два разных файла конфигурации содержат одинаковый server_name, обработается только первый из них по порядку чтения файлов Nginx. Второй сайт при этом останется недоступен, а никакой явной ошибки в логах может не появиться — используйте nginx -T чтобы найти такой конфликт.
Забытая ссылка в sites-enabled
Файл конфигурации может быть полностью корректным, но если для него не создана символическая ссылка в sites-enabled, Nginx его просто не увидит и не загрузит. Проверить какие сайты реально активны можно командой ls -la /etc/nginx/sites-enabled/.
Часто задаваемые вопросы
Сколько сайтов можно разместить на одном Nginx?
Технического ограничения на количество server blocks в Nginx нет. Практический предел определяется ресурсами сервера — объёмом RAM и производительностью CPU, необходимыми для обработки суммарного трафика всех сайтов, а не самим Nginx.
Нужен ли отдельный IP-адрес для каждого сайта?
Нет. Все сайты могут работать на одном IP-адресе одновременно, потому что Nginx различает их по заголовку Host из HTTP-запроса, а не по IP-адресу. Отдельные IP-адреса могут понадобиться только для специфических случаев, например для разделения сайтов на сетевом уровне или для некоторых конфигураций почтовых серверов.
Что произойдёт если открыть сайт напрямую по IP-адресу сервера?
Ответит либо server block с флагом default_server, если он явно настроен, либо первый server block в порядке чтения файлов, если default_server не задан нигде. Чтобы контролировать это поведение осознанно, рекомендуется всегда явно настраивать отдельный блок с default_server и return 444;.
Можно ли использовать один SSL-сертификат для нескольких доменов?
Да, если сертификат выпущен как мультидоменный (SAN-сертификат) или как wildcard-сертификат для поддоменов одного домена. Let’s Encrypt поддерживает выпуск сертификата сразу на несколько доменов через флаг -d, указанный несколько раз в одной команде certbot.
Как быстро проверить какие сайты сейчас активны на сервере?
Список активных сайтов — это содержимое директории sites-enabled: команда ls -la /etc/nginx/sites-enabled/. Полную развёрнутую конфигурацию со всеми деталями каждого сайта покажет команда nginx -T.
Несколько сайтов на одном VPS — эффективный способ использовать ресурсы сервера. На UFO.Hosting даже базовая конфигурация с 2 ГБ RAM комфортно обслуживает несколько небольших сайтов через один Nginx.
Похожее
Все статьи
Nginx как reverse proxy: настройка и конфигурация
Reverse proxy на Nginx — это когда Nginx принимает внешние запросы на порту 80 или 443 и перенаправляет их на приложение которое работает на внутреннем порту (3000, 8000, 8080). Снаружи видно только Nginx, само приложение сети не касается. Три строки…
Node.js через NVM и PM2: установка и запуск на Ubuntu
NVM (Node Version Manager) позволяет устанавливать несколько версий Node.js на одном сервере и переключаться между ними без переустановки. PM2 — менеджер процессов, который держит Node.js-приложение запущенным в фоне, перезапускает его при падении и добавляет в автозагрузку. Вместе они закрывают большинство…