VirtualHost with wildcard VirtualDocumentRoot

18,020

I use them :) You forgot about switching off canonical names - unfortunately I don't know why there must be ServerAlias in my configuration - it just won't work without it - code below is tested and working

<Directory "C:/LocalServer/*/public">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
    Require local
</Directory>

<VirtualHost *:80>
    # Apache will form URLs using the hostname supplied by the client
    UseCanonicalName Off

    # available aliases to use
    ServerAlias *.lab *.lab2

    # where to put them
    VirtualDocumentRoot "C:/LocalServer/%2/%1/public/"
</VirtualHost>
Share:
18,020

Related videos on Youtube

Mike Rockétt
Author by

Mike Rockétt

Updated on September 16, 2022

Comments

  • Mike Rockétt
    Mike Rockétt over 1 year

    I'm trying to create a fallback for my virtual hosts. My configuration looks like this:

    # Fetch all pre-defined hosts
    
    Include "conf/extra/vhosts/*.conf"
    
    # Fallback
    
    NameVirtualHost *:80
    
    <Directory "C:/LocalServer/usr">
        Options Indexes FollowSymLinks Includes
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
    <VirtualHost *:80>
        VirtualDocumentRoot "C:/LocalServer/usr/%-1/projects/%-2+/public/"
    </VirtualHost>
    

    The objective here is the following: If I try to access http://test.lab/, I want it to automatically pick up the following directory: C:/LocalServer/usr/lab/projects/test/public/.

    Now, I have created the folders, and an empty index file (index.php). Nonetheless, Apache keeps showing me an empty Directory Index ("Index of").

    No quite sure what to do now. Have tried a few things, none of which seem to work.

    Any ideas?

    Update - 1 June

    I am now using this code, based on the first answer (well, the only one):

    <VirtualHost *:80>
        UseCanonicalName Off
        ServerAlias *.lab
        VirtualDocumentRoot "C:/LocalServer/%2/%1/public"
        <Directory "C:/LocalServer/%2/%1/public">
            Options Indexes FollowSymLinks Includes
            AllowOverride All
            Order allow,deny
            Allow from all
        </Directory>
    </VirtualHost>
    

    I now get an Access forbidden error from Apache. One would surely, normally, receive this error when the directory does not exist? C:/LocalServer/lab/test/public does exist, and an empty index.php resides in the public directory.

    The error in the general error log: [client 127.0.0.1:49342] AH01797: client denied by server configuration: C:/LocalServer/lab/test/public/

    If I remove the <Directory/> group, nothing changes. I still get the error. (Can I even use %n in that group?)

    Quick Note:

    The reason it wasn't working before was due to the fact that I had other Virtual Hosts being imported, by means of the Include "conf/extra/vhosts/*.conf" instruction. Commenting it out (and thus making the Labs rule the only one) initiated the Access forbidden error.

    Also note that I am no longer using the usr folder - each Lab is now in the lab folder, under LocalServer.

    Update 2

    It seems that the <Directory/> block does not allow for variables to be inserted, like VirtualDocumentRoot does.

    Update 3 - Solution Found

    It is now working - would not have been able to do it without the help. Here's the final code:

    <VirtualHost lab:80>
        UseCanonicalName Off
        ServerAlias *.lab
        VirtualDocumentRoot "C:/LocalServer/%2/%1/public"
        <Directory "C:/LocalServer/lab/*/public">
            Options Indexes FollowSymLinks
            AllowOverride All
            Order Allow,Deny
            Allow from all
        </Directory>
    </VirtualHost>
    

    Update 4 (April 2015)

    New Directive, for those interested (using latest Apache 2.4):

    <VirtualHost *:80>
        UseCanonicalName Off
        ServerAlias *.local
        VirtualDocumentRoot "D:/home/%-2+/public_html"
        <Directory "D:/home/*/public_html">
            Require all granted
            AllowOverride All
            Options Indexes FollowSymLinks
        </Directory>
    </VirtualHost>
    

    This, with the combination of Acrylic DNS Proxy, makes magic.

    Update 5 (December 2016)

    I'm now using a Macro approach.

    # Directory Macro - Default Directory configuration on a per-vhost basis
    
    <Macro Directory $dir>
        <Directory "z:/var/www/$dir/public_html">
            Require all granted
            Options Includes Indexes FollowSymLinks
            AllowOverride All
        </Directory>
    </Macro>
    
    # LocalSub Macro - For specific *.*.local subs that require their own root
    
    <Macro LocalSub $sub $domain>
        <VirtualHost 127.0.0.1>
            ServerName $sub.$domain.local
            DocumentRoot “z:/var/www/$domain/$sub/public_html”
            Use Directory $domain/$sub
        </VirtualHost>
    </Macro>
    
    Use LocalSub blog rockettpw
    
    # Main virtual host
    
    <VirtualHost 127.0.0.1>
        UseCanonicalName Off
        ServerAlias *.local *.*.local
        VirtualDocumentRoot “z:/var/www/%-2/public_html”
        Use Directory *
    </VirtualHost>
    
    • Mike Rockétt
      Mike Rockétt about 9 years
      @SuperSpy - Naturally, I have an entry for each domain (though, I'm no longer using *.lab). That said, I'm currently trying to get Acrylic DNS Proxy working. I would think so, but I always keep my server on the same drive as my site-data.
    • Mike Rockétt
      Mike Rockétt about 9 years
      Your NameVirtualHost may be set to *:80, which means the VirtualHost directive must be set to match. I have updated my question to show you what I am currently using.
    • Huelfe
      Huelfe about 8 years
      Update 4 was exactly what I was looking for! Thank you so much!
  • Mike Rockétt
    Mike Rockétt almost 11 years
    I did try something quite similar to that, albeit with a few more lines of the usual stuff. Will try your attempt exactly as you have it. Hope it works! :)
  • Ochi
    Ochi almost 11 years
    try to define <Directory> as I did it - it must work - "Require local" is optional
  • Mike Rockétt
    Mike Rockétt almost 11 years
    Thanks! I picked up the Directory problem - and initially just used lab/. But, yours is better. Wouldn't have been able to fix this without you - many thanks!
  • Hussain KMR Behestee
    Hussain KMR Behestee over 8 years
    I think "Require all granted" is a must.