Working with domains locally

Most beginners use "http://localhost/…/app/ for their project when they develop locally.
This can have several possible downsides if not carefully avoided. Especially with (hardcoded) paths in css, js, images or any other browser url related issue.

So the better way to work locally is to simulate the real world using a domain like structure without any subfolders.
This can easily be achieved by setting up a vhost and adding the local ip + desired domain in the host file.

By properly routing the domain to your webroot folder you will also have the cleanest setup (all files outside the webroot scope are not reachable and no additional rewrite folder jumping is necessary). As this should be the default setup for any live application, why not doing it this way for development, as well? So this is win-win situation in every way. I use it for all projects. The only thing still going through the localhost domain is phpmyadmin.

Note: Do not use this for local networks. Here it is not good practice to invent top-level-domains (details). Use the following only for your local (single) computer environment.

Windows

On Windows its as easy as it gets.
Lets say we have a project called "foo" and our live website is "www.foo.bar".

First go to "C:\Windows\System32\drivers\etc" and edit the host file (with admin rights!).
You simply need to add one line below "127.0.0.1 localhost":

127.0.0.1 foo.local

You dont need to add any top level domains (neither foo.bar nor www.foo.bar etc!).
But it is wise to add .local as your TLD – as shown above.

After saving this file we need to tell apache what to do with this virtual domain.
I will explain it using WAMPserver but XAMPP should not be too different.

In WAMP the file is located in "C:\wamp\bin\apache\Apache[version]\conf\extra"
and called "http-vhosts.conf".

We copy and paste the first block and edit it to sth like this:

<VirtualHost *:80>
    ServerAdmin [email protected]
    DocumentRoot "C:\wamp\www\foo\trunk\app\webroot"
    ServerName foo.local
    
    <Directory C:\wamp\www\foo\trunk\app\webroot\>
        Options -Indexes
        AllowOverride All
        
        Order allow,deny
        allow from all
    </Directory>
</VirtualHost>

Please correct the absolute paths according to your file system! 🙂
Important is that /webroot itself is the last folder to be included. Its wrong to include anything below for security and performance reasons.

Last but not least you might have to include this vhost.conf file in your httpd.conf file (default is commented out) in "C:\wamp\bin\apache\Apache[version]\conf":

# Virtual hosts
# Include conf/extra/httpd-vhosts.conf

Simply remove the second dash (#):

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

Linux

Operating systems from the Linux family can often surprize you with differences you will have to consider, but most systems are fairly standard.

The hosts file you need to edit is usually "/etc/hosts".
You will find "127.0.0.1 localhost" entry there, create it if isn’t there.

You can now add your new hostname to the same line after a whitespace, like 127.0.0.1 localhost foo.local, or add 127.0.0.1 foo.local as an additional line, similar to Windows part.

Apache settings are usually kept in "/etc/apache" or "/etc/apache2".
Virtual host settings can be kept in either a single file or a directory with multiple files. In the former case you may proceed as described in the Windows example (mind the slashes in paths). If you have a directory
for many vhost configuration files, your best choice is to create new file with your new hostname in the filename, like 20_foo_vhost.conf, and have it contain your VirtualHost block, like this:

<VirtualHost *:80>
    ServerName foo.local
    ServerAdmin root@foo
    DocumentRoot "/var/www/htdocs/foo/trunk/app/webroot/"
    
    <Directory "/var/www/htdocs/foo/trunk/app/webroot/">
            Options -Indexes +FollowSymLinks
            AllowOverride All
            Order allow,deny
            Allow from all
    </Directory>

# This block is optional and can be omitted.
# However, rights management *is* important.
# Look for more useful options you can set here.
    <IfModule mpm_peruser_module>
        ServerEnvironment apache apache 
        # replace with your webserver user and group
        # like www-data or htdocs or what have you.
    </IfModule>
</VirtualHost>

Please note that in this case it has to be the full path down to the webroot folder, as well.

Outcome

After restarting the apache server you should now be able to access your project with the following url:
http://foo.local/
Congratulations. Now all hard-coded links in css or js documents like "background-url: /img/xyz.gif" will now work.

If the real url of the "members register" function is "http://www.foo.bar/members/register/" it will now be locally "http://foo.local/members/register/"

Have fun developing!

Advanced setup

You can even include your whole webroot htaccess file in your vhost setting (and remove all htaccess files from your app).
Inside the directory directive then add this:

<Directory /var/www/htdocs/foo/trunk/site/webroot/>
    Options -Indexes
    RewriteEngine On
    AllowOverride None

    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    Order allow,deny
    allow from all
</Directory>

I also added a non-www to www 301 redirect and disabled the index display that can be activated on some systems by default.

Note the AllowOverwrite None directive.
This way it is supposed to be even faster since it doesn’t look for any htaccess file in your directory path.

Update 2013-01-22

Better use foo.local instead of just foo to overcome some webservice issues during development which need a TLD to properly work.
Others like to use www.foo.dev (ending with dev as TLD and including the subdomain part). This also works, of course.
You can also simulate multiple subdomains this way, of course: mysubdomain.foo.local. As many as you want.

Update 2013-08-08 Nginx

David Yell wrote sth about CakePHP configuration for nginx.

1 Comment

  1. Great write-up! Worked like a charm. I was always just a tad bit confused with the apache.org examples. Now, I’m not.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.