Advanced vhosts Configuration
This post assumes you know a little bit about setting up your own Apache configuration and want to configure your vhosts
(virtual hosts).
When I first set up my vhosts
, this is all I really had in my httpd-vhosts.conf
file:
VirtualDocumentRoot /Users/cameron/Sites/%0
That's great if all I want to do is create a directory, such as cameronspear.test
in my ~/Sites
folder, but if I want anything a little more advanced, I have to make some changes.
Problem
I knew you could set your own <VirtualHost>
setting in your httpd-vhosts.conf
, but if I did that, I'd lost my VirtualDocumentRoot
setting, so if I have 40 directories in my ~/Sites
directory, then I would have to create 40 entries in my httpd-vhosts.conf
, which is lame. I can no longer just create a folder and be done. I have to open another file and create a new <VirtualHost>
entry.
Solution
Create a bogus entry. Apparently, if you don't have a <VirtualHost>
node that matches, it will use the settings in the first <VirtualHost>
node it encounters.
For example, here's what the first entry looks like:
# this is the default if it does not match any of the other VirtualHost entries (must remain FIRST in the list)
<VirtualHost *:80>
ServerName bogusname.bogus
UseCanonicalName Off
VirtualDocumentRoot /Users/cameron/Sites/%0
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog /var/log/apache2/access_log vcommon
# stop favicon errors!
Redirect 404 /favicon.ico
<Location /favicon.ico>
ErrorDocument 404 "No favicon"
</Location>
</VirtualHost>
No if I go to cameronspear.test
, and there isn't another entry, it will look in /Users/cameron/Sites/cameronspear.test
for the document root.
Now, in any other custom entries I create, I just have to set VirtualDocumentRoot none
and then define a specific DocumentRoot
.
Why is this useful?
Let's say you are working with a framework, and the framework isn't in the document root. Many frameworks can configure themselves so pretty much all the PHP is outside the document root, and only public resources, like CSS and JS are in the document root (with the exception of an index.php, which all traffic is commonly driven through).
For example, by default, the Laravel framework puts the application directory, system files and bundles directory in a directory above the public document root. So under the old method, we would want laravel.test
to be the document root, but to get to what Laravel expects to be the document root (be default), we'd have to go to lavavel.test/public
, which isn't what we want.
So what we can do is create a new entry in httpd-vhosts.conf
making sure it's after our bogus entry:
# Laravel's dir is one level above public index
<VirtualHost *:80>
ServerName laravel.test
DocumentRoot /Users/cameron/Sites/laravel.test/public
VirtualDocumentRoot none
</VirtualHost>
Now, (after restarting apache), laravel.test
will point where we want it to (to the public
folder).
What else cool can you do?
Another thing I have set up, is I have a subdomain forwarded completely to my local machine (i.e. *.dummy.cameronspear.com
would all forward to my IP address). I can create an entry and add the following:
ServerAlias laravel.dummy.cameronspear.com
And now someone from the outside world could see a site on my local computer by going to laravel.dummy.cameronspear.com
. Great for showing someone a project you're working on without having to first upload it to a remote server, etc.
Just make sure your site is secure, or else people could gain access to your personal computer.
It's also nice, because you can set a different ErrorLog
path for a specific site or suite of sites, or set up any other customizations you might need for a specific site, without loosing the ability to just create a new directory and have the site just work.