Mod-Rewrite

使用 Apache 2.4 的大規模虛擬主機

  • May 22, 2017

我想使用 a 中設置的VirtualDocumentRootRewriteRule

Apache文件說:

要確定的另一件事是文件根目錄(使用 DocumentRoot 配置並通過 DOCUMENT_ROOT 環境變數可用於 CGI 腳本)。在正常配置中,核心模組在將 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}預設值由 httpd.conf 中的 DocumentRoot 設置。我希望%{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>

有解決辦法嗎?

在與@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 5.6 和 PHP 7 安裝了 PHP-FPM,並按如下方式設置了我的虛擬主機配置:

<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,它將從 Document Root 中拉出/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

我還沒有遇到任何問題。這很簡單並且有效。

引用自:https://serverfault.com/questions/606830