Mass virtual hosting with Apache 2.4

apache-2.2apache-2.4mod-rewritevirtualhost

I would like to use the value set by VirtualDocumentRoot in a RewriteRule.

The Apache documentation says:

The other thing to determine is the document root (configured with DocumentRoot and available to CGI scripts via the DOCUMENT_ROOT environment variable). In a normal configuration, this is used by the core module when mapping URIs to filenames, but when the server is configured to do dynamic virtual hosting, that job must be taken over by another module (either mod_vhost_alias or mod_rewrite), which has a different way of doing the mapping. Neither of these modules is responsible for setting the DOCUMENT_ROOT environment variable so if any CGIs or SSI documents make use of it, they will get a misleading value.

Refering to the documentation, it seems I won't be able to use %{DOCUMENT_ROOT} in RewriteRule. But after looking for alternative solutions, I found this ticket (title: DOCUMENT_ROOT environment variable set incorrectly with VirtualDocumentRoot) saying it has been “fixed in 2.4.1”.

I am using the latest (stable) version of Apache:

$ httpd -v
Server version: Apache/2.4.9 (Unix)
Server built:   Jun 18 2014 03:07:48

… but it doesn't seem to work for me. When testing, %{DOCUMENT_ROOT} has the default value set by DocumentRoot in httpd.conf. I would like %{DOCUMENT_ROOT} (or any other variable I could use) to be dynamically set by VirtualDocumentRoot.

Here is what I would like to use in 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>

Is there a solution?

Best Answer

I accomplished this using mod_proxy and mod_proxy_fcgi, noting the "Proxy via Handler" section: https://httpd.apache.org/docs/trunk/mod/mod_proxy_fcgi.html

I needed to be able to run both PHP 5.6 and PHP 7 on my local dev sites so I installed PHP-FPM for both PHP 5.6 and PHP 7 and setup my vhosts config as follows:

<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>

As the "Proxy via Handler" section explains:

When FastCGI is configured this way, the server can calculate the most accurate PATH_INFO.

With this configuration I can:

Visit a local dev site http://example.hack and it'll be pulled from the Document Root /Volumes/CODE/projects/example and be passed through to my PHP 5.6 PHP-FPM service SetHandler proxy:fcgi://127.0.0.1:9056.

Visit a local dev site http://example.php and it'll be pulled from the same Document Root /Volumes/CODE/projects/example but it'll be passed through to my PHP 7 PHP-FPM service SetHandler proxy:fcgi://127.0.0.1:9070

I haven't had any problems with this yet. It's simple and works.