Динамический корневой путь домена nginx на основе имени хоста?

11

Я пытаюсь настроить свой сервер разработки nginx / PHP с помощью базовой конфигурации master / catch-all vhost, чтобы при необходимости я мог создавать неограниченное количество ___.framework.locдоменов .

server {
        listen 80;
        index index.html index.htm index.php;

        # Test 1
        server_name ~^(.+)\.frameworks\.loc$;
        set $file_path $1;
        root    /var/www/frameworks/$file_path/public;

        include /etc/nginx/php.conf;
}

Тем не менее, nginx отвечает с ошибкой 404 для этой установки. Я знаю, что nginx и PHP работают и имеют разрешение, потому что используемый localhostмной конфиг работает нормально.

server {
        listen 80 default;
        server_name localhost;
        root /var/www/localhost;
        index index.html index.htm index.php;

        include /etc/nginx/php.conf;
}

Что я должен проверить, чтобы найти проблему? Вот копия того php.conf, который они оба загружают.

location / {
        try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {

        try_files $uri =404;

        include fastcgi_params;
        fastcgi_index index.php;

        # Keep these parameters for compatibility with old PHP scripts using them.
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Some default config
        fastcgi_connect_timeout        20;
        fastcgi_send_timeout          180;
        fastcgi_read_timeout          180;
        fastcgi_buffer_size          128k;
        fastcgi_buffers            4 256k;
        fastcgi_busy_buffers_size    256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_intercept_errors    on;
        fastcgi_ignore_client_abort off;
        fastcgi_pass 127.0.0.1:9000;

}
Xeoncross
источник

Ответы:

12

Почему бы просто не использовать:

server_name *.frameworks.loc;
root /var/www/frameworks/$http_host/public;
Майкл Хэмптон
источник
Это именно то, что я искал!
Xeoncross
13

Конфигурация Nginx - это не программа, а декларация. Когда вы используете конфигурацию, как это:

server {
        server_name ~^(.+)\.frameworks\.loc$;
        ...
        set $file_path $1;
        root    /var/www/frameworks/$file_path/public;
}

Нет способа гарантировать, что ваша setдиректива будет выполнена раньше root.

Но есть трюк с mapдирективой, которую я люблю использовать. Он опирается на то, что mapоценивается раньшеlocation

http {
  map $http_host $rootpath {
    ~^(.?<mypath>+)\.frameworks\.loc$  $mypath;
    default                            /      ;
  }
  ....
  root /var/www/frameworks/$rootpath
}
DukeLion
источник
Это выглядит весело, я планирую играть больше с картой сейчас. Я также не знал, что файлы конфигурации не обрабатывались линейно.
Xeoncross
Какой смысл $mypathздесь? Это нигде не используется.
kodeart
@kodeart $mypath- это группа результатов для регулярных выражений ~^(.?<mypath>+)\.frameworks\.loc$и $rootpathрезультат для всего трюка с картой.
Фабио Монтефусколо
4

В дополнение к великому ответу DukeLion , мне нужно было изменить линию

~^(.?<mypath>+)\.frameworks\.loc$ $mypath;

в

~^(?P<mypath>.+)\.frameworks\.loc$ $mypath;

в моем /etc/nginx/nginx.confфайле, как предложено здесь .

Добавление

root /var/www/frameworks/$rootpath

в /etc/nginx/sites-available/defaultработал отлично после этого.

zub0r
источник
0

Может быть, вы можете посмотреть в lighttpd также. Он имеет встроенную поддержку именно то, что вы просите здесь. Это вызов mod_evhost .

Включить evhost

Добавьте следующие строки в ваш lighttpd.conf. Если вы используете базовый дистрибутив Debian / Ubuntu, просто создайте мягкую ссылку или скопируйте из /etc/lighttpd/conf-available/10-evhost.confв /etc/lighttpd/conf-enabled/.

    # http://redmine.lighttpd.net/wiki/1/Docs:ModEVhost
    server.modules + = ("mod_evhost")
    evhost.path-pattern = "/ home / www /% _"

%_(Подстановочные) в evhost.path-Паттен средства использовать полное доменное имя (например, www.example.com). Запрос на www.example.com будет автоматически направлен на root-документ /home/www/www.example.com/.

Добавить дополнительный сайт так же просто, как создать другой каталог /home/wwwс полным доменным именем. Без изменений в конфигурационном файле Lighttpd.

Существуют и другие шаблоны, которые можно использовать для построения структуры каталогов. Они как следовать

    %% => знак%
    % 0 => доменное имя + tld
    % 1 => тлд
    % 2 => доменное имя без тдл
    % 3 => имя субдомена 1
    % 4 => имя субдомена 2
    % _ => полное доменное имя

Подробная информация здесь .

PS: Включить PHP также легко, если вы работаете на платформе Debian / Ubuntu. Просто включите 10-fastcgi.confи 15-fastcgi-php.conf.

Джон Сиу
источник
0

NGINX использует библиотеку регулярных выражений PCRE.
Начиная с NGINX v0.8.25 server_nameдиректива разрешает именованные захваты .

Именованные захваты в регулярных выражениях создают переменные ( 0.8.25 ), которые впоследствии можно использовать в других директивах. При использовании именованных круглых скобок NGINX автоматически устанавливает переменную для каждой именованной круглой скобки во время оценки имен серверов (я полагаю).

Я использую следующий фрагмент кода для «ограждения» среды разработчиков. «Пользователь» относится к их имени пользователя и «проекту» проекта, над которым они работают:

# ...
server_name ~^(?<user>[^.]+)\.(?<proj>[^.]+).dev.local-server.com;
root /home/$user/www/$proj;
# ...

Обратите внимание, что конфигурация nginx является декларативной, и поэтому статические объявления всегда могут быть быстрее по сравнению с вычисляемыми во время выполнения значениями и переменными. Оценка регулярных выражений является относительно дорогостоящей, я думаю, она должна использоваться с экономией в сильно загруженных (производственных) средах.

Stphane
источник