Virtual hosts и server-блоки
Что такое virtual host
Virtual host — отдельный сайт на одном сервере. Один Nginx может обслуживать десятки доменов: example.com, api.example.com, nobleweb.ru.
Nginx определяет, какой сайт отдавать, по server_name (домену).
Простой server-блок
Файл /etc/nginx/sites-available/example.com:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
Разбор
listen 80; — слушать порт 80 (HTTP).
listen [::]:80; — то же для IPv6.
server_name example.com www.example.com; — для каких доменов.
root /var/www/example/public; — корневая папка с файлами.
index index.php index.html; — файл по умолчанию.
location / — что делать для всех URL.
try_files $uri $uri/ /index.php?$query_string; — если файл существует — отдать, иначе — в index.php (Laravel).
Стандартный конфиг для Laravel
server {
listen 80;
listen [::]:80;
server_name example.com;
root /var/www/skills/api/public;
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Ключевые моменты Laravel
root .../public; — важно: корень — папка public, не корень проекта. Иначе .env доступен снаружи.
try_files — Laravel использует фронт-контроллер public/index.php. Все запросы идут туда.
location ~ \.php$ — обработка PHP через fastcgi_pass на PHP-FPM.
fastcgi_pass unix:/var/run/php/php8.5-fpm.sock; — сокет PHP-FPM. Проверь свою версию:
ls /var/run/php/
# php8.5-fpm.sock
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; — путь к PHP-файлу. $realpath_root защищает от path traversal через симлинки.
location ~ /\.(?!well-known).* — запрет доступа к скрытым файлам (.env, .git). (?!well-known) — исключение для .well-known/acme-challenge (нужен для Let's Encrypt).
Включение сайта
1. Создай конфиг:
sudo nano /etc/nginx/sites-available/example.com
2. Симлинк в sites-enabled:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
3. Проверь:
sudo nginx -t
4. Перезагрузи:
sudo systemctl reload nginx
5. Проверь:
curl -I http://example.com
# HTTP/1.1 200 OK
Удаление default-конфига
Nginx по умолчанию отдаёт страницу приветствия. Убери:
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl reload nginx
Иначе если server_name не совпадёт — Nginx отдаст эту страницу.
Проверка server_name
Если домен не совпадает с server_name, Nginx отдаёт первый server-блок из конфига. Это может быть чужой сайт.
Проверь:
curl -I http://wrong-domain.com
Если это не 404, а чужой сайт — значит default не удалён или порядок server-блоков неверный.
Поддомены
Для api.example.com:
server {
listen 80;
server_name api.example.com;
root /var/www/skills/api/public;
# ...
}
Каждый поддомен — свой server-блок.
Wildcard
Для всех поддоменов одного домена:
server_name *.example.com;
Для любых доменов (для default-блока):
server_name _;
Проверка текущего server-блока
Полезная команда:
nginx -T | grep -A 20 "server_name example.com"
Покажет весь блок.
Итог
Алгоритм:
- Создать конфиг в
sites-available/ - Симлинк в
sites-enabled/ nginx -tsystemctl reload nginx
Для Laravel: корень — public/, PHP — через fastcgi_pass.
Дальше — reverse proxy для Laravel.