Top.Mail.Ru

Nginx Server Blocks: несколько сайтов на одном VPS

13
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

Nginx как reverse proxy: настройка и конфигурация

Reverse proxy на Nginx — это когда Nginx принимает внешние запросы на порту 80 или 443 и перенаправляет их на приложение которое работает на внутреннем порту (3000, 8000, 8080). Снаружи видно только Nginx, само приложение сети не касается. Три строки…

nvm node.js

Node.js через NVM и PM2: установка и запуск на Ubuntu

NVM (Node Version Manager) позволяет устанавливать несколько версий Node.js на одном сервере и переключаться между ними без переустановки. PM2 — менеджер процессов, который держит Node.js-приложение запущенным в фоне, перезапускает его при падении и добавляет в автозагрузку. Вместе они закрывают большинство…