MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


Location, Location, Location: Tips for Storing Web Site Files

by Patrick Crowley
05/16/2003

If you're like me, you've figured out how to install and configure your very own web development environment on Mac OS X. You've got Apache. You've got PHP. You've got MySQL (and phpMyAdmin, too). And, like a proud father, you've already cranked out a bunch of whiz-bang, dynamic web sites -- all on a Mac.

But, as your kids grow older, they're bound to go through some growing pains. And one of the first things you'll need to figure out is where to store your web site's files. Should they be in the Sites folder? The Documents folder? What are your options?

Here are three common approaches -- which address the needs of basic, intermediate, and advanced web developers.

Option 1: Use Your Sites Folder

Pros: No work required
Cons: Files must be stored in your Sites folder

Related Reading

Mac OS X in a Nutshell
A Desktop Quick Reference
By Jason McIntosh, Chuck Toporek, Chris Stone

If you're just beginning to experiment with web development on Mac OS X, storing files in your Sites folder (AKA ~/Sites/) is definitely your best option. (Note: if you're already a Mac web-dev whiz, you can definitely skip this part.)

If you haven't already, make sure you enable Web Sharing (via System Preferences->Sharing), so that your copy of the Apache web server is fired up and ready to serve.

Once you've started web serving, to access any file or directory in your ~/Sites/ folder, just type 127.0.0.1 (also referred to as "localhost") into your browser, followed by your user name, and then the file or directory name you wish to access, like so:


~/Sites/     --------> http://127.0.0.1/~your_user_name/
~/Sites/site/	-----> http://127.0.0.1/~your_user_name/site
~/Sites/page.html ---> http://127.0.0.1/~your_user_name/page.html

Each time you start working on a new web site, all you need to do is create a directory for the new site, drag it into your Sites folder, and, voila, that site is now being served!

Option 2: Use Aliases

Pros: Serve files from anywhere on your Mac
Cons: Need to know under-the-hood OS X stuff

So let's step things up a notch. Let's say you already have an existing file structure for your projects, and you're none too pleased about having to move everything over to the Sites folder. What do you do?

Easy! Just add a couple of aliases to your Apache config file (/etc/httpd/httpd.conf) and you'll be able to serve your web sites from wherever they happen to be located -- not just from the Sites folder.

There's one catch, though. Like many of OS X's UNIX underpinnings, your Apache config file is hidden from view. So the first thing you need to do is get a tool that will let you open the config file. To do this, you should use a text editor capable of opening and editing hidden files (like BBEdit) or, alternately, use a utility like TinkerTool that can enable the Finder to show all hidden files. (Note: it's always a good idea to back the config file up before making any changes.)

OK, so once you've got that sucker open, scroll down to the Aliases section and take a look. Here's how it should look:


Alias /icons/ "/usr/share/httpd/icons/"

<Directory "/usr/share/httpd/icons">
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

As you can see, each alias contains two parts: an Alias directive, which is the actual name used to access your site from the browser (as in http://127.0.0.1/alias), and then a <Directory> tag, which points to the actual location of the files you wish to serve.

Let's say you want to serve up some files from a project that's stored deep down in your Document directory, such as /Users/your_name/Documents/Clients/Client 4/site/. Just add a new set of Alias and Directive commands to your config file, like so:


Alias /icons/ "/usr/share/httpd/icons/"
Alias /client4/ "/Users/your_name/Documents/Clients/Client 4/site/"

<Directory "/usr/share/httpd/icons">
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

<Directory "/Users/yourname/Documents/Clients/Client 4/site/">
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

Once you've made these changes, save your httpd.conf file and restart Apache (by turning Web Sharing off and then back on again in the Sharing pane in System Preferences).

Now, you should be able to access your new project by just entering http://127.0.0.1/client4/ straight into your browser! (And, of course, for each additional site you wish to serve from outside your Sites folder, just add a new Alias/Directory combo, restart your server again, and you're good to go.)

...

But wait, there's a catch -- and, if you're using PHP, it's an important one.

By default, PHP is configured to work properly with any files in your Sites directory. But should you serve files from a different location, you'll need to tweak your PHP configuration file, as well.

Now -- don't get scared on me -- the truth is Mac OS X, by default, doesn't have a php.ini file. So you'll actually need to make your own! But don't worry. It's easy.

  1. Add a lib directory to /usr/local/.
  2. Download a sample php.ini file from the PHP mothership.
  3. Rename the file you just downloaded to php.ini.
  4. Move the file to /usr/local/lib/.

Now that you're all set, open up your new php.ini file and scroll down to the Paths and Directories section, which should look like this:


;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

; UNIX: "/path1:/path2"  
;include_path = ".:/php/includes"

First, remove the semi-colon in front of include_path, so that we can enable includes.


include_path = ".:/php/includes"

I know what you're thinking -- "Why do we need to tweak our include path, Patrick?" Well, dear Mac web developer, it turns out that PHP apps often rely on something called the include() command, which, you guessed it, allows PHP to include (or load) external files. Being a talented Mac OS X web developer, you'll probably wish to enable this feature at some point, either for use in other people's code or your own.

So, next, as you can probably guess, you need to add the directory from our earlier example to the include_path variable, so that PHP will work in this directory the same way it works in the Sites folder. (Use this trick each time you add a new alias to Apache's config file that might use PHP, separating each new include path with a colon, as in the example below.)


include_path = ".:/php/includes:/Users/your_name/Documents/Clients/
    Client 4/site/"

Ok, that's it! You're now fully set up to serve both HTML and PHP files using aliases!

Option 3: Enable Virtual Hosts

Pros:  Use customized URLs (no need for 127.0.0.1)
           Use absolute file paths
           No php.ini editing necessary
Cons: Easy to screw up

But wait! There's more! This next option is the trickiest of the three, but it offers the greatest ability to make your local development server truly function like a production server.

And this gets to why I wrote this article in the first place. I had to figure out how to enable virtual hosts over the weekend -- and a thousand Google searches later, I realized that while there may be a cornucopia of documentation on Apache, MySQL, PHP, and the like, virtually none of it deals with Mac OS X! (Come on, people! Start documenting your experiences with this stuff, will ya?)

OK, with my rant out of the way, let's get busy with this virtual host stuff. Basically, with virtual hosts, a single Apache web server can serve multiple web sites from the same IP address. And not only that, you can actually use different, customized domain names for each web site.

In other words, instead of accessing files through 127.0.0.1, you can use a real (or simulated) domain name. So, to the untrained eye, your local web site will look like it's being served straight off the web — without any 127.0.0.1 gobbledygook.

Not only are there a lot of technical benefits to doing things this way (support for absolute file paths, no need to mess with PHP includes, etc.), but this stuff is perfect for client demos! You can run presentations straight off of your PowerBook and no one ever needs to know you're not on the Web.

Since this is exactly the sort of thing that many web developers on OS X really need, let's set up some virtual hosts!

To get started, scroll down to the very bottom of your Apache config file (/etc/httpd/httpd.conf) and find the NameVirtualHost section.


# Use name-based virtual hosting.
#
#NameVirtualHost

First, let's enable name-based virtual hosts, which we'll do by removing the # comment prefix from the last line.


# Use name-based virtual hosting.
#
NameVirtualHost

Next, let's specify the IP address to which our name-based virtual host names will resolve: which, of course, is our old friend 127.0.0.1.


# Use name-based virtual hosting.
#
NameVirtualHost 127.0.0.1

Now, we need to set up our VirtualHost directives. Using the example provided in the Apache config itself, we'll first add a virtual host for our existing Sites folder. We do this to ensure that we'll still be able to access web sites stored in the Sites folder using our existing 127.0.0.1-based addresses once we've enabled virtual hosts.

As you can see, we place 127.0.0.1 in the ServerName field, and then, with DocumentRoot, we specify where the files for our virtual host are stored -- the Sites folder.


<VirtualHost 127.0.0.1>
ServerName 127.0.0.1
DocumentRoot /Users/your_name/Sites
</VirtualHost>

With that behind us, we'll now add a VirtualHost directive using the same logic, but this time, we'll do it using my web site iCalShare as an example.

Since we still need to access the real iCalShare web site, we can't use the icalshare.com domain for our virtual host. If we did use that domain, whenever we entered icalshare.com into our browser, it wouldn't know whether to load the local site, or the external one.

Since this is a test server, we'll append a "test" subdomain to our primary domain name, making our complete server name test.icalshare.com. That name won't conflict with the existing iCalShare domain name, and it also tells us a little about the purpose of this server.

So let's place our new name in both the VirtualHost and ServerName tags. And, then, once again, we'll use DocumentRoot to point to the location of the files for this site, which are stored a few levels down in our Documents folder.


<VirtualHost test.icalshare.com>
DocumentRoot /Users/patrick/Documents/Projects/iCalShare/wwwroot
ServerName test.icalshare.com
</VirtualHost>

Now I bet you're asking, "How does my browser know that test.icalshare.com is a local request, and that icalshare.com is a remote one?" Good question! And the answer is ... because we're going to tell it!

The Web as we know it is actually strung together using IP addresses, not domain names. Each time you enter a web site domain name into your browser, it's actually translating that name into an IP address, which it does by checking with a DNS server. Once the DNS server finds an IP address match for the domain name you entered, you're magically transported to the web site you're seeking.

As it turns out, with Mac OS X, when you enter a domain name, your browser first checks with /etc/hosts to see if there's a matching IP address. If no match is found, the browser will forward the domain name on to a DNS server. So, by editing /etc/hosts, you can actually change where your browser goes when you enter various domain names. And this is exactly how we'll get your machine to recognize the virtual hosts we set up earlier.

So, open up your /etc/hosts file, and you should be looking at something like this:


127.0.0.1	localhost
255.255.255.255	broadcasthost
::1             localhost

To enable the virtual host we set up earlier, just add a new entry to the file, as we've done below for our iCalShare example.


127.0.0.1	localhost
127.0.0.1	test.icalshare.com
255.255.255.255	broadcasthost
::1             localhost

For each virtual host you need, just create a new line that begins with 127.0.0.1, followed by a space or tab, and then the actual domain name.

So that's it! Save your /etc/httpd/httpd.conf and /etc/host files, restart Apache, and your vanity domain should now work like magic!

(Note: I've only touched the surface of all of the nifty things you can do with virtual hosts. Further reading on this topic is recommended.)

Final Thoughts

And, now patient readers, in the tradition of the great Jerry Springer, I leave with you a final thought ... get out there and go crazy with this stuff! And if you discover something cool in your web-development-on-OS-X travels, don't forget to share it!

Patrick Crowley is the creator of iCalShare, the iCal calendar directory, which was recently featured in Steve Jobs' keynote speech at Macworld San Francisco 2003.


Return to MacDevCenter.com

Copyright © 2009 O'Reilly Media, Inc.