Виртуальный хост (vhost, Virtual Host) — метод размещения нескольких веб-сайтов на одном сервере с одним IP-адресом. Сервер (nginx, Apache, IIS) читает заголовок Host входящего HTTP-запроса и направляет его в конфигурацию соответствующего сайта. Это основа виртуального хостинга — сотни сайтов на одном физическом сервере.
Как работает
HTTP/1.1 требует от клиентов передавать заголовок Host с каждым запросом (RFC 2616). Это позволяет одному серверу обслуживать множество доменов. В nginx каждый сайт конфигурируется блоком server:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
}
server {
listen 80;
server_name another.com;
root /var/www/another;
}
В Apache — директивой VirtualHost:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example
</VirtualHost>
Типы vhost:
- Name-based — различаются по заголовку Host. Самый распространённый тип. Требует HTTP/1.1 (все современные клиенты).
- IP-based — каждый сайт на отдельном IP. Нужно при использовании старых клиентов или протоколов без Host.
- Port-based — разные порты для разных сайтов. Нетипично для web, используется для внутренних сервисов.
SNI (Server Name Indication, RFC 6066) — расширение TLS, позволяющее name-based vhost работать с HTTPS: клиент передаёт имя сервера в процессе TLS-хендшейка до шифрования, что позволяет серверу выбрать нужный SSL-сертификат.
История
Name-based virtual hosting появился с RFC 2068 (HTTP/1.1, 1997). Директива VirtualHost в Apache введена в Apache 1.1 (1996). До HTTP/1.1 каждый сайт требовал отдельный IP — это ограничивало рост веба. Массовое внедрение shared hosting стало возможным именно благодаря name-based vhost. SNI стандартизован в TLS Extensions (RFC 3546, 2003), включён в RFC 6066 (2011).
Конфигурация vhost с несколькими PHP-версиями
Современный хостинг позволяет каждому vhost использовать свою версию PHP через PHP-FPM пулы. В nginx каждый server-блок указывает на свой fastcgi_pass сокет:
server {
server_name site1.example.com;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
}
server {
server_name site2.example.com;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}
Каждый PHP-FPM пул работает под своим системным пользователем, что обеспечивает изоляцию: файлы site1 недоступны скриптам site2 даже при одинаковых правах файловой системы.
На что обращать внимание
Порядок server-блоков в nginx имеет значение: если ни один server_name не совпал, запрос обрабатывает первый блок или блок с default_server. Не настроенный default_server может раскрывать внутренние конфигурации. Каждый vhost должен иметь отдельный error_log и access_log для разграничения логов разных клиентов. Настройка через панель ISPmanager позволяет создавать vhost через GUI без ручного редактирования конфигов. В Docker-средах vhost часто управляется динамически через Labels + nginx-proxy или Traefik.