Массовый виртуальный хостинг с 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.

http://httpd.apache.org/docs/current/mod/mod_macro.html

Другие вопросы по тегам