Массовый виртуальный хостинг с Apache 2.4
Я хотел бы использовать значение, установленное VirtualDocumentRoot
в RewriteRule
,
Документация Apache гласит:
Другая вещь, которую нужно определить, - это корень документа (настроенный с помощью DocumentRoot и доступный для сценариев CGI через переменную среды DOCUMENT_ROOT). В обычной конфигурации это используется основным модулем при сопоставлении URI с именами файлов, но когда сервер настроен для динамического виртуального хостинга, это задание должно быть передано другому модулю (либо mod_vhost_alias, либо mod_rewrite), который имеет другой способ сделать отображение. Ни один из этих модулей не отвечает за установку переменной среды DOCUMENT_ROOT, поэтому, если ее используют какие-либо CGI или документы SSI, они получат неверное значение.
Ссылаясь на документацию, кажется, я не смогу использовать %{DOCUMENT_ROOT}
в RewriteRule
, Но после поиска альтернативных решений я обнаружил, что этот тикет (заголовок: переменная среды DOCUMENT_ROOT неправильно установлен с VirtualDocumentRoot) говорит, что он "исправлен в 2.4.1".
Я использую последнюю (стабильную) версию Apache:
$ httpd -v
Server version: Apache/2.4.9 (Unix)
Server built: Jun 18 2014 03:07:48
... но это не похоже на работу для меня. При тестировании %{DOCUMENT_ROOT}
имеет значение по умолчанию, установленное DocumentRoot в httpd.conf. мне бы хотелось %{DOCUMENT_ROOT}
(или любую другую переменную, которую я мог бы использовать) для динамической установки VirtualDocumentRoot
,
Вот что я хотел бы использовать в httpd-vhosts.conf:
<VirtualHost *:8080>
ServerName dev
ServerAlias *.dev
VirtualDocumentRoot "/usr/local/var/www/.dev/%-2+"
RewriteRule ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/$1" [P]
</VirtualHost>
Есть ли решение?
4 ответа
Посмотрев с John Auld во многих направлениях (спасибо за ваше время и помощь), я наконец нашел решение. Как я сказал в предыдущем комментарии, это не на 100% идеально, но достаточно хорошо для меня.
Для ясности вот что я хотел получить в httpd-vhosts.conf:
<VirtualHost *:8080>
ServerName dev
ServerAlias *.dev
VirtualDocumentRoot "/usr/local/var/www/.dev/%-2+"
RewriteRule ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/$1" [P]
</VirtualHost>
И вот что я придумала:
<VirtualHost *:8080>
ServerName dev
ServerAlias *.dev
VirtualDocumentRoot "/usr/local/var/www/.dev/%-2/%-3"
RewriteCond %{SERVER_NAME} (?:([^.]+)\.)?([^.]+)\.dev
RewriteRule ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/usr/local/var/www/.dev/%2/${:%1|www}/$1" [P]
</VirtualHost>
я использую RewriteCond
захватывать части %{SERVER_NAME}
и повторно использовать их в RewriteRule
,
Есть две группы захвата: поддомен (%1
) и домен (%2
). Субдомен необязателен, поэтому я использую синтаксис ${map:value|default}
установить значение по умолчанию для субдомена, когда пусто.
VirtualDocumentRoot
имеет свое значение по умолчанию, когда часть (%N.M
) не доступен. Как сказано в документации:
Если N или M больше, чем количество доступных частей, то используется единственное подчеркивание.
Вот почему мне пришлось использовать небольшой "трюк", чтобы он работал с необязательным поддоменом:
ln -sfv /path/to/the/project/www /path/to/the/project/_
Если вы думаете о способе сделать это только для конфигурации, оставьте комментарий, и я отредактирую свой ответ с вашим вкладом.
Я сделал это с помощью mod_proxy и mod_proxy_fcgi, отметив раздел "Прокси через обработчик": https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html
Мне нужно было иметь возможность запускать как PHP 5.6, так и PHP 7 на моих локальных сайтах разработчиков, поэтому я установил PHP-FPM для PHP 5.6 и PHP 7 и настроил конфигурацию vhosts следующим образом:
<Virtualhost *:80>
VirtualDocumentRoot "/Volumes/CODE/projects/%1"
ServerName sites.hack
ServerAlias *.hack
UseCanonicalName Off
<FilesMatch "\.php$">
Require all granted
SetHandler proxy:fcgi://127.0.0.1:9056
</FilesMatch>
</Virtualhost>
<Virtualhost *:80>
VirtualDocumentRoot "/Volumes/CODE/projects/%1"
ServerName php7.php
Serveralias *.php
UseCanonicalName off
<FilesMatch "\.php$">
Require all granted
SetHandler proxy:fcgi://127.0.0.1:9070
</FilesMatch>
</Virtualhost>
Как объясняется в разделе "Прокси через обработчик":
Когда FastCGI настроен таким образом, сервер может рассчитать наиболее точный PATH_INFO.
С этой конфигурацией я могу:
Посетите местный сайт разработчиков http://example.hack
и он будет извлечен из корня документа /Volumes/CODE/projects/example
и пройти через мой PHP 5.6 PHP-FPM сервис SetHandler proxy:fcgi://127.0.0.1:9056
,
Посетите местный сайт разработчиков http://example.php
и он будет извлечен из того же корня документа /Volumes/CODE/projects/example
но он будет передан моему PHP 7 PHP-FPM сервису SetHandler proxy:fcgi://127.0.0.1:9070
У меня еще не было проблем с этим. Все просто и работает.
Следующее работало просто отлично для меня на 2,4
UseCanonicalName Off
<VirtualHost *:80>
ServerName auto.dev
ServerAlias *.dev
VirtualDocumentRoot /Users/yourusername/Sites/auto/%1/public
<Directory ~ "/Users/yourusername/Sites/auto/.*/public">
Options Indexes FollowSymlinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Обратите внимание, что я сопоставляю общую папку в корневой папке
Переменная недоступна в файлах конфигурации apache.
Взгляните на mod_macro, который позволяет использовать переменные в файлах conf.