PHP 5 and LightTPD on Mac OS X
Thu 8 Feb 07 19:39
This is another article originally posted at another blog which I have copied over here.
As I was saying before I was so rudely interrupted…
Hey, all. Sorry for the lack of updates recently (if there really are people out there who care that much…) but my brand new MacBook Pro's hard drive thought it would be funny to bite the big one on me, so I was at reduced productivity for a while… Well, anyway, I'll try to get back to writing articles semi-regularly. And since I'm currently in the process of restoring all the programs and stuff on my hard drive anyway, I think I'll start on how to install PHP 5 and the LightTPD web server on Mac OS X using MacPorts (which, you may recall, I blogged about earlier).
First, to answer a question that may pop up… Why install LightTPD when Mac OS X already comes with the Apache web server built in? Well, I suppose it's a matter of personal taste. I personally like the web server to be running all the time, so that way, when I decide I want to start coding my site, I don't have to mosey over to a Terminal window or System Preferences to start it up first. On the other hand, since it's going to be constantly running, the web server should be using up as little RAM and CPU resources as possible. So I want to use a "lightweight" server so that the fact that it's running all the time won't interfere too much with my frames-per-second on Call of Duty 2 and stuff. On the other other hand, it can't be so lightweight that it doesn't support PHP, which is the point of all of this in the first place, right? So, for me (and possibly for you), LightTPD is the best compromise.
So enough blather and let's get installing. (I'm assuming you've already installed MacPorts as I discussed in my earlier entry. First, let's install LightTPD. This is the easy part; just head into your Terminal, type sudo port install lighttpd, and wait.
When LightTPD is done compiling, it's time for PHP — but first, a note on just how this is going to work. With Apache, scripting languages like PHP are generally built as a "module" which are actually compiled into Apache to a certain extent. This keeps things fairly speedy, but it has some problems; most notably, due to the extent that the two are tied together, it's possible for a poorly-written or malicious PHP script to cause the PHP executer to crash or fail in such a way as to bring down Apache as well. If you're a web host, that's not an ideal situation, so some smart people came up with FastCGI. I won't go into technical details here, but basically what FastCGI does is that it lets script executers like PHP run separately from the web server and then pass the results of their execution over to the web server without drastically slowing things down. That way, if PHP crashes, the web server is not affected at all. Recent versions of Apache support FastCGI, but LightTPD, in keeping with its desire to be compact, only supports FastCGI.
The problem is that, if we compile PHP using just port install php… well, nothing will happen because there is no "php" package; we have to use "php4" or "php5." But anyway, if we use port install php5, the PHP executable it installs will not work with FastCGI, so LightTPD won't be able to do anything with it. So what we need to do is to tell PHP that we want it to consider FastCGI when it compiles. Now if we were compiling by hand like a bunch of Unix nerds, we would do this by editing complicated-looking configuration files before the compilation, but since we're using MacPorts, there's an easier way.
Some MacPorts packages support "variants." Variants are essentially pre-set ways of modifying the configuration files for compilation, but they're much easier to use. To check the possible variants for a package, you type port variants packagename. Try it now with PHP: port variants php5. In the list that appears, you'll see fastcgi. A-ha! (You'll also see variants for Apache, MySQL and PostgreSQL. If we were building PHP as an Apache module, we'd use the Apache variant. More on the other two later.)
So now how do we build PHP using the fastcgi variant… Again, it's easy; we just add a plus sign followed by the variant name after the standard install command. So: sudo port install php5 +fastcgi. Bam! (If you wanted MySQL and/or PostgreSQL support included in PHP, then as you can probably guess, you'd add the +mysql5 and/or +postgresql variants. I personally prefer SQLite's ease of use, and since it's built into PHP 5 by default, I don't need to use a variant to install support for it.) Now just wait as normal while everything installs.
Okay, so now we've got LightTPD and PHP 5 installed; now we have to edit some configuration files to make sure that they'll be able to see each other and work correctly. "What?" I hear you say. "I thought I wouldn't have to edit any stupid configuration files to get this to work!" Well, before I get remanded to a looney bin for hearing voices, let me assure you that I'll walk you through it. (All this info is on LightTPD's documentation pages, but what I'll give you below will be specific to a Mac OS X installation done with MacPorts, as we just did.) Keep in mind that you'll need your administrator password to edit some of these files.
The first thing we want to edit is PHP's configuration file, which is located at /opt/local/etc/php.ini. Now if you look in that directory, you'll see there's no php.ini there yet, but there is a php.ini-recommended. Duplicate that file and rename it to php.ini. Now open up php.ini in your text editor of choice (I'm assuming if you're reading this that you're smart enough to know the difference between a text editor and a word processor, and I can forego the standard lecture) and add this line somewhere in the file:
cgi.fix_pathinfo=1
Save and close php.ini; we're done with it for now.
Now we want to edit LightTPD's config file, which is at /opt/local/etc/lighttpd/lighttpd.conf. Similarly, you will at first only see lighttpd.conf.default in this directory; copy it and rename it to lighttpd.conf. Open that up.
Near the top of that config file is a list of various modules LightTPD can use. Most of them will be "commented out" by having a hash at the beginning of the line. Remove the hash in front of the line that says "mod_fastcgi".
The section right below that is where you will tell LightTPD where to look for the web pages for it to serve. I personally like to use the Sites directory in my Home directory, as is Mac OS X's default. The section immediately below that will tell LightTPD where we want it to store the error log file; I like to put them in a "Logs" directory inside my Sites directory. So that part of my config file looks like this:
## a static document-root, for virtual-hosting take look at the
## server.virtual-* options
server.document-root = "/Users/Albright/Sites/"
## where to send error-messages to
server.errorlog = "/Users/Albright/Sites/Logs/lighttpd.error.log"
Keep in mind that, whatever paths you use, you'll need to have those directories created and ready to go before we fire up LightTPD.
Scroll down a little bit and you'll see this:
## set the event-handler (read the performance section in the manual)
# server.event-handler = "freebsd-kqueue" # needed on OS X
Well, we're on OS X, aren't we? So remove the first hash on that second line to uncomment that line.
Scroll down a bit further, and we'll see a setting for accesslog.filename. You'll want to set that to where you want the access log file to be written. I used "/Users/Albright/Sites/Logs/access.log".
One more thing. Last thing; I promise. Scroll down until you find the FastCGI configuration settings. At the top of that section will be some settings to use if we want to use PHP, which we do. We'll want to uncomment those lines, then set the settings as such:
fastcgi.server = ( ".php" =>
( "localhost" =>
(
"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/opt/local/bin/php-fcgi"
)
)
)
Note how we've changed the value of "bin-path".
Okay, that should do it for that config file. Save it. Now I realize that I just told you to do a lot of stuff, and it might have been confusing, so to help you out, here's my config file as it's saved on my system, so you can compare it to yours if you think you've missed something.
All right, now let's try starting LightTPD and getting this show on the road. First, of course, to avoid confusing things, you'll want to stop any other web servers currently running on your system, including Mac OS X's built-in Apache installation ("Personal Web Sharing" in the Sharing panel of System Preferences).
But before we do that, if you have a firewall installed on your system, it might be smart to set it up to not allow incoming web requests (port 80), if it is not configured as such already. Otherwise, everyone on the internet will be able to access your web server, and you probably don't want that. If you don't have another firewall installed on your system, Mac OS X's built-in one will suffice; go into the Sharing panel of System Preferences, click the Firewall tab, and make sure you see "Firewall On;" otherwise, click the "Start" button.
Let's test what LightTPD thinks of our config file; we can have it test the file without fully starting up by running this command in the Terminal:
lighttpd -t -f /opt/local/etc/lighttpd/lighttpd.conf
If all goes well, it'll spit back Syntax OK. Now let's start LightTPD for real:
lighttpd -D -f /opt/local/etc/lighttpd/lighttpd.conf
If there was some error that the testing mode we did above didn't catch, LightTPD will spit it back to you and quit. If it doesn't appear to spit anything at you, then it's working! Fire up a web browser and go to http://localhost/. You should see whatever is the index file in the server.document-root directory we specified above. I recommend putting a <?php phpinfo(); ?> file in that directory and accessing it in your web browser, both to make sure PHP is working fine and to see all the goodies that were included with the PHP installation.
Now if you want to quit LightTPD because you need to change a configuration file setting or something, simply switch back to the Terminal window you started it in and press Control-C.
Okay, one last trick up our sleeve. I want LightTPD to start up automatically when I start our computer so that I don't have to go back to a Terminal window to start it up again. Fire up your text editor again and paste in this bit of text:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.lighttpd</string>
<key>OnDemand</key>
<false/>
<key>Program</key>
<string>/opt/local/sbin/lighttpd</string>
<key>ProgramArguments</key>
<array>
<string>/opt/local/sbin/lighttpd</string>
<string>-f/opt/local/etc/lighttpd/lighttpd.conf</string>
</array>
</dict>
</plist>
Save it as /Library/LaunchDaemons/net.lighttpd.plist. Now, if you restart your computer, LightTPD should be running, so you can just fire up your web browser and see your site. (Thanks to forehle for the hints on this; I've modified his original code to align it with our MacPorts-installed version of LightTPD.)
Phew! What a long article. But I hope someone, somewhere out there finds it useful. There are some other nifty things you can do with LightTPD's configuration, but I won't go into them now.
Get more great Ray Gun Robot content sent directly to your feed reader or email inbox! Subscribe today!
Articles & Links — Via Email
Articles Only — Via Email
4 Comments | 0 Trackbacks |
| ![]()
Trackbacks
Comments
#1 | Stewart Wachs | 12 Jan 08 19:38
Thanks for the post. It was a real time-saver!
#2 | Akshay Dodeja | 2 Jun 08 01:57
You site has been pretty helpful. Port installation of lighttpd + php is not as trivial as i thought. Files are all over the place. Finally got it to work. Thanks again.
#3 | Sho | 15 Jun 08 15:50
Saved me a lot of time, and memory. Really helpful when you only have 1 gb of ram.
#4 | Olle Jonsson | 16 Jun 08 11:01
To quickly review what happens to your installation upon using a variant, read the Portfile:
mate $(port file php5)
(You don't have to use the $() form, you can use backticks around the expression to be evaluated first, instead. Anyway.)

