使用 Apache 2.4 进行大规模虚拟托管

使用 Apache 2.4 进行大规模虚拟托管

我想使用在VirtualDocumentRoota 中设置的值RewriteRule

阿帕奇文档说:

另一件需要确定的事情是文档根目录(使用 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>

有解决办法吗?

答案1

我使用 mod_proxy 和 mod_proxy_fcgi 实现了这一点,注意到“通过 Handler 进行代理“ 部分:https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html

我需要能够在我的本地开发站点上同时运行 PHP 5.6 和 PHP 7,因此我为 PHP 5.6 和 PHP 7 安装了 PHP-FPM,并按如下方式设置了我的 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

在从多方面进行研究之后@约翰·奥尔德(感谢您的时间和帮助),我终于找到了解决方案。正如我在先前的评论,它不是 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/_

如果你想办法做到这一点仅配置,留下评论,我会根据您的贡献编辑我的答案。

答案3

该变量在 apache 配置文件中不可用。

看一下 mod_macro,它允许在 conf 文件中使用变量。

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

答案4

对于我来说,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>

请注意,我正在映射到根文件夹中的公共文件夹

相关内容