Возникла необходимость в автоматическом режиме создавать поддомены, но возиться с каждым доменом очень не хотелось, тем более правила работы у всех хостов одинаковые, а значит эти правила можно описать единожды.
Реализовать единый конфиг Nginx для нескольких сайтов можно при помощи масок или регулярных выражений директивы server_name
Недавно я писал про Wildcard сертификат Let's Encrypt для всех поддоменов, теперь настало время сделать для них единый конфиг.
Стоит учесть что при одном конфиге для всех поддоменов у них будет одна конфигурация и работать они будут по одним и тем же правилам.
В моем случае поддомены должны были работать на PHP и отдавать статику. Это нормальная схема. А вот случай когда один поддомен должен работать с использованием PHP, а другой на Node.js нужно рассматривать с двумя разными конфигами.
Итак, получается вот такой конфиг:
server {
listen 80;
# принимаем все входящие соединения на поддомены byurrer.ru
# далее используем переменную $host для обозначени домена
server_name *.byurrer.ru;
root /var/www/$host/;
# если директории виртуального хоста нет, тогда ответ 444
# https://nginx.org/ru/docs/http/request_processing.html
if (!-d /var/www/$host) {
return 444;
}
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
Этот конфиг вводит ряд ограничений правил:
/var/www/
А теперь вариант конфига с использованием Wildcard сертификата:
# принимаем все входящие соединения с 80 порта (http)
# на все поддомены byurrer.ru и перенаправлем их на https
server {
listen 80;
server_name *.byurrer.ru;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name *.byurrer.ru;
root /var/www/$host/;
if (!-d /var/www/$host) {
return 444;
}
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
ssl_certificate /etc/letsencrypt/live/byurrer.ru/fullchain.pem;
ssl_trusted_certificate /etc/letsencrypt/live/byurrer.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/byurrer.ru/privkey.pem;
}
Теперь сделаем конфиг для нескольких сайтов при помощи регулярных выражений.
Реглярные выражения в конфиге Nginx совместимы с PCRE, поэтому можно использовать именованные выделения, типа
domain
как в примере.
server {
listen 80;
server_name ~^(?<domain>.+)$;
if (!-d /var/www/$domain) {
return 444;
}
index index.html index.htm index.php;
root /var/www/$domain/;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
Разница между масками и регулярными выражениями в примерах почти незначительна. С масками мы используем переменную host
, а с регулярными выражения именнованное выделение domain
.
Редиректы и сертификаты для конфига оставлю в качестве домашнего задания, там не сложно догадаться и трудно ошибиться :)
Как оказалось, при использовании Nginx вовсе необязательно дублировать конфиг виртуального хоста, если правила работы одинаковы.
Догадаться о таком решении при небольшом опыте использвания оказалось не трудно, а тут еще и русскоязычна документация :)