Yeah, yeah, yeah. You've got your Dashboard, your Automator, your Spotlight, your uber-Safari, and your RSS screensaver. And they're great, dandy, zippidity-doo-dah. It'd be terrific if there were something new under the hood for web serving, right? Apache 2.0! Some, any, version of MySQL. Oooh! Ooooh! I want this one, and that one, and whee! Well, guess what, dear readers? You got nothin'. An incremental update here, a minor tweakage there, but there really hasn't been many changes under the hood when it comes to web serving. This is the exact same swan song from Panther: little new, bub.
And you know what? There's absolutely nothing wrong with that. With very minor modification, and even then only GUI related, the articles I wrote two years ago are still relevant. Everything you've learned about the Apache web server still applies. If you've read my previous series, you still know how to look in the
error_log for debugging purposes,
install CGI scripts, enable and test PHP, restrict access by host, IP, or password, customize errors, create .htaccess files, and more. If we go back further to my series from 2002, there's more on aliasing directories, pretty autoindexes, and anonymous or environment access. All this stuff still works! Once you learn how to do something with Apache, it's pretty much guaranteed to always function.
Where does that leave us? In this new series, we're going to focus on the application level: instead of learning more about Apache, we're going to treat it as the serving framework it really should be. We'll talk about setting up our own Wiki, content management system (no, no, not weblog software), and some helper utilities that'll make our management of databases a bit easier. If you've got some particular applications you'd like a tutorial on, leave a comment below and we'll consider it for inclusion.
But first, let's whirlwind through the basics: turning on the Apache web server, learning a teensy bit of its configuration, and enabling and testing PHP. If you need a calmer, smoother recap than what follows, I heartily suggest rereading one of my earlier series; save for a few minor changes, they hold up to time. Don't hesitate to ask questions in the comments section below.
The easiest way to begin is through System Preferences. Click the Apple Menu, choose System Preferences, and then Sharing. Under the Services tab you'll see a number of options, only one of which is of immediate value. See that Personal Web Sharing service? Select it and click the Start button to fire up the built-in Apache web server.
By default, Apache has been configured to serve your personal web pages from a directory based on your Mac OS X short username. You can find your short username in the Accounts preference panel. If your short username is "morbus," you can access your personal web site by opening a local web browser and typing
localhost) is pretty special--every computer has one. Both names represent the computer itself; by accessing
127.0.0.1 in your browser, you visit the Apache activated via the Sharing preference panel.
But, how do you make your web pages available to folks on the World Wide Web? The answer is found back in Sharing. Click the Personal Web Sharing service and note the IP or hostname at the bottom of the window--that address is how others can access your web server. If you're behind a router, you'll probably see a local address instead. You can find your publicly available IP at checkip.dyndns.org/.
In some cases, outsiders may not be able to access your server:
There are a number of locations and files that are vitally important to the configuration and serving of content available through Apache. What follows is a quick rundown of the six most crucial bits:
error_logwill provide everything you need to know when something goes wrong. These files are located in
/var/log/httpd/, and most technical support (such as
#apache) will want to know exactly what your
error_logsays before even suggesting a fix. While you can certainly use the
tailshell utility to peer at these files whenever necessary, I've found it much easier to simply run a few tailDash Dashboard widgets instead (use "httpd log" and "error log"). The importance of the
error_logcan not be understated: even if the error you're seeing in your browser doesn't tell you much (by design), the one found in your
error_logwill always be dead-on.
/etc/httpd/httpd.conf. This file has been slightly tweaked by Apple to support some additional features, but remains relatively similar to the defaults you'll see with Apache under Windows or any version of Linux. Apple has also gone a step further, however, and created
/etc/httpd/users/, which contains one configuration file per graphical user you've created. If your username is "morbus", you should have a
morbus.conffile. By default, these user files contain a minimal bit of configuration to support user websites, such as
http://127.0.0.1/~morbus/. When changing the web server config, it ultimately doesn't matter which of these files you put your additions in, but I've come to prefer the user version, just because it has less of a chance of being modified during the next OS update. Server-wide configuration additions within a user-configuration file work just fine.
/Library/WebServer/Documents/. User URLs, like
http://127.0.0.1/~morbus/are located at
/Users/morbus/Sites/. If you navigate to these locations in your Finder, you'll see some introductory files that tell you more about Apache and web serving under OS X. Read 'em and delete 'em (or back 'em up).
Now that we know where our configuration files are, the first thing to fiddle with is enabling PHP, an easy-to-learn web programming language that most of our forthcoming applications are coded in. Open your favorite text editor (BBEdit,
nano, etc.), and load
/etc/httpd/httpd.conf. You can read a great primer on using
sudo to authenticate) with O'Reilly's An Introduction to the Tiger Terminal. BBEdit will take care of the authentication required when we save our changes.
The Apache configuration file is heavily commented and contains sane defaults for pretty much anything you'd want to do. To change these defaults or, in this case, to enable PHP, we'll simply search for a string matching what we're interested in. Tell your text editor to search for
php, and the first and second matches should be:
#LoadModule php4_module libexec/httpd/libphp4.so #AddModule mod_php4.c
These two lines tell Apache to load the module that enables PHP--here they are commented out (i.e. prefixed with the
# character). Uncomment these two lines (remove the
# character but don't touch anything else) and save your changes. Changes to these configuration files take effect the next time Apache has restarted. I'll show you how to do that below but first, let's see what else we find in our
<IfModule mod_php4.c> # If php is turned on, we respect .php and .phps files. AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps # Since most users will want index.php to work we # also automatically enable index.php <IfModule mod_dir.c> DirectoryIndex index.html index.php </IfModule> </IfModule>
This block of configuration only comes into play if the PHP module has been enabled (
IfModule...). They tell us that PHP will be interpreted in any file that has an extension of
php, and that a source file ends in
phps. In addition,
index.php should be treated as a default page when nothing more specific is requested and
index.html doesn't exist. This is just fine; save your configuration.
We've now got to restart Apache so that it can enact our configuration changes. One way is just to toggle the Stop button for the Personal Web Sharing service in the Sharing System Preference, and then click Start again. Unfortunately, if we've made a mistake in our configuration edits, the GUI won't tell us, instead opting to endlessly try unsuccessfully. A far more reliable way is through the
apachectl shell utility shipped with Apache. Hop into your Terminal and type
apachectl configtest; you should see something like:
apachectl configtestProcessing config directory: /private/etc/httpd/users/*.conf Processing config file: /private/etc/httpd/users/morbus.conf Syntax OK
This is just perfect. On the other hand, if we made a mistake--say, deleting one character too many on the
LoadModule line--we'd see a stern rebuking of our mistake with line number:
apachectl configtestSyntax error on line 240 of /etc/httpd/httpd.conf: Invalid command 'oadModule', perhaps mis-spelled or defined by a module not included in the server configuration
Get into the habit of running
apachectl configtest after any configuration change; as long as you see
Syntax OK, you're cleared for restarting. We'll use
apachectl again, this time prefixed with
sudo to authenticate as the
root user, and with the
sudo apachectl restartPassword: /usr/sbin/apachectl restart: httpd restarted
restart stops the Apache server if it is currently running, and then starts it immediately. It is, oddly, equivalent to running
sudo apachectl stop and
sudo apachectl start. If you don't see any errors (common ones include a configuration typo or forgetting to use
sudo), then Apache is now running with your config changes.
You can confirm that PHP has been enabled with your
error_log. Whenever you enable a third-party module (such as PHP), Apache will happily add that information into the
Server header of every request it serves (though it has become common practice by most Linux distros to "obscure" the header with
ServerTokens in an attempt at "security"). It also logs this information in the
tail to check out the latest information logged there, where you should see something along these lines (shortened for brevity):
tail /var/log/httpd/error_log[notice] Apache/1.3.33 (Darwin) configured -- resuming normal operations [notice] Accept mutex: flock (Default: flock) [notice] SIGHUP received. Attempting to restart Processing config directory: /private/etc/httpd/users/*.conf Processing config file: /private/etc/httpd/users/morbus.conf [notice] Apache/1.3.33 (Darwin) PHP/4.3.11 configured -- resuming normal operations [notice] Accept mutex: flock (Default: flock)
Take a look at the two lines that start with
Apache/1.3.33. The first one is before your configuration change; the second, with the addition of
PHP/4.3.11, confirms that the PHP module has loaded. Depending on your activity, you may not see both entries in the last 10 lines of
grep notice /var/log/httpd/error_log, or the tailDash widget can F12 your way to logfile monitoring.
Oftentimes, however, simply enabling a module in the configuration file doesn't mean it has been configured properly. Thankfully, with PHP it's easy to test; simply create an
index.php file with the following contents and save it into
<?php phpinfo(); ?>
http://127.0.0.1/ and, if everything is roses, you should see a rather large page full of PHP debugging information: what it was compiled with, what settings are currently enabled, and blah, blah, blah. An awful lot of stuff here, and only a wee bit you'll need to care about.
Unfortunately, this concludes our whirlwind start of Apache web serving under Tiger. As mentioned, I've skimped on the hand-holding so that those with a firm foothold from my previous articles, or their own spelunking, won't wander off in a daydream.
Next time, we'll be focusing on tweaking PHP to be more secure, and installing and configuring the MySQL database server. With that scaffolding in place, we'll start looking at some of the best-of-breed applications that have made LAMP (Linux + Apache + MySQL + PHP/Perl/Python) the preferred architecture of many a web developer. If you have suggestions for where you'd like this series to take you, wax poetic in the comments below.
Kevin Hemenway is the coauthor of Mac OS X Hacks, author of Spidering Hacks, and the alter ego of the pervasively strange Morbus Iff, creator of disobey.com, which bills itself as "content for the discontented."
Return to the Mac DevCenter
Copyright © 2009 O'Reilly Media, Inc.