apache

Making it Easier to Spawn php-cgi on Debian and Ubuntu

Apache is a great web server, but sometimes I need something a bit more lightweight. I already have a bunch of sites using lighttpd, but I'm planning on switching them to nginx. Both nginx and lighttpd use FastCGI for running php. Getting FastCGI up and running on Ubuntu (or Debian) involves a bit of manual work which can slow down deployment.

The normal process to get nginx and php-cgi up and running is to install the spawn-fcgi package, create a shell script such as /usr/local/bin/php-fastcgi to launch it, then a custom init script, after making both of these executable you need to run update-rc.d then finally should be right to go. Each of these manual steps increases the likelihood of mistakes being made.

Instead, I created a deb contains a configurable init script. It is pretty simple, the init script calls spawn-fcgi with the appropriate arguments. All of the configuration is handled in /etc/default/php-fastcgi. The main config options are:

  • ENABLED - Enable (or disable) the init script. default: 0 (disabled)
  • ADDRESS - The IP address to bind to. default: 127.0.0.1
  • PORT - The TCP Port to bind to. default: 9000
  • USER - The user the php scripts will be excuted as. default: www-data
  • GROUP - The group the php scripts will be executed as. default: www-data
  • PHP_CGI - The full path to the php-cgi binary. default: /usr/bin/php5-cgi

The last 3 variables are not in the defaults file as I didn't think many users would want/need to change them, feel free to add them in if you need them.

Once you have set ENABLED to 1, launch the init scipt by executing sudo /etc/init.d/php-fastcgi start. To check that it is running run sudo netstat -nplt | grep 9000 and you should see /usr/bin/php5-cgi listed. Now you can continue to configure your webserver.

The package depends on php5-cgi and spawn-fcgi, which is available in Debian testing/squeeze, unstable/sid, along with Ubuntu karmic and lucid. For earlier versions of ubuntu you can change the dependency in debian/control from spawn-fcgi to lighttpd and disable lighttpd once it is installed so you can get spawn-fcgi . I haven't tested this approach and wouldn't recommend it.

You can grab the http://davehall.com.au/sites/davehall.com.au/files/php-fastcgi_0.1-1_all.deb">binary package and install it using dpkg or build it yourself from the source tarball.

For more information on setting up nginx using php-cgi I recommend the linode howto - just skip the "Configure spawn-fcgi" step :)

A Virtual Host per Project

Not long before my old laptop got to the end of it usable lifespan I started playing with the Zend Framework in my spare time. One of the cool things about ZF is that it wants to use friendly URLs, and a dispatcher to handle all the requests. The downside of this approach, and how ZF is organised, it works best if you use a Virtual Host per project. At first this seemed like a real pain to have to create a virtual host per project. One Saturday afternoon I worked through the apache docs and found a solution - then I found it fantastic. Rather than bore you with more of my views on Zend Framework, I will explain how to have a virtual host model that requires a little work up front and is very low maintenance.

It gets tedious copying and pasting virtual host config files each time you want to start a new project, so instead I let Apache do the work for me.

I added a new virtual host config file called projects to

/etc/apache2/sites-available
. The file contains

UseCanonicalName Off

LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon

<Directory /home/dave/Projects>
Options FollowSymLinks
AllowOverride All
</Directory>

NameVirtualHost 127.0.0.2
<VirtualHost 127.0.0.2>
	ServerName projects

	CustomLog /var/log/apache2/access_log.projects vcommon

	VirtualDocumentRoot /home/[username]/Projects/%1/application/www
	AccessFileName     .htaccess
</VirtualHost>

The important bit is the VirtualDocumentRoot directive which tells Apache to map a hostname to a path. I use an IP address from the 127.0.0.0/8 range for the virtual host, so they aren't accessible to the outside world and I don't have to worry about it changing every time I check locations.

All of my projects live under ~/Projects and each one gets a directory structure that looks something like this.

[projectname]
  |
  +- notes - coding notes, like grep output when refactoring etc
  |
  +- resources - any reference material or code snippets
  |
  +- application - the code for the project
     |
     +- www - document root for vhost

There are usually other paths here too, but they vary from project to project.

To make this work there are few more steps. First enable the new virtual host

$ sudo a2ensite projects

Don't reload apache yet.

Next you need to add the apache module

$ sudo a2enmod vhost_alias

Time to edit your

/etc/hosts
file so you can find the virtual hosts. Add a line similar to this
127.0.0.2 projects phpgw-trunk.project [...] phpgw-stable.project

Now you can restart apache.

$ sudo /etc/init.d/apache2 reload

This is handy for developing client sites - especially using drupal.

Now my

/var/www/index.html
is just an empty file.

I am getting a bit bored with adding entries to

/etc/hosts
all the time. If I get around to adding dnsmasq with wildcard hosts to the mix, I will post a follow up.

This setup is based on my current dev environment (Ubuntu Hardy), but it also works on older versions of Ubuntu. The steps should be similar for Debian and derivatives. For other distros, it should work, just how to make it work may be a little different. Feel free to post tips for others in the comments.