Installing lighttpd and FastCGI for Catalyst
From Dev411: The Code Wiki
One of the big benefits of using Catalyst web framework (http://www.catalystframework.org) is its ability to run on a variety of web servers and engines. Catalyst makes running your app on lighttpd and FastCGI breeze. FastCGI allows Catalyst to run in a persistent Perl process with the lighttpd web server. As an aside, while the FastCGI process is persistent, the connection between lighttpd and FastCGI isn't. The LiteSpeed webserver (http://litespeedtech.com/) supports persistent FastCGI connections but isn't open source (though there is a free standard version).
The following are notes on getting lighttpd running with FastCGI and Catalyst. Catalyst 5.65, lighttpd 1.4.10 and CentOS 4.2 were used for testing.
| Table of contents |
Installing lighttpd
I prefer to compile programs from source. Lighttpd is available from lighttpd.net (http://www.lighttpd.net).
To enable FastCGI with lighttpd, it must be configured with a few options. They are:
$ ./configure \ --enable-fastcgi \ --enable-discard-path \ --enable-force-cgi-redirect \ $ make $ su - # make install
This will install the lighttpd binary in /usr/local/sbin. Now you should copy two files into place, the startup file and the configuration file.
Configuring startup
lighttpd 1.4.10 comes with init.d files for SuSE and Red Hat/CentOS. The SuSE file is doc/rc.lighttpd and the Red Hat file is doc/rc.lighttpd.redhat.
The init.d files assume that the lighttpd binary is in /usr/sbin/lighttpd while the default install location is /usr/local/sbin/lighttpd. You'll have to either move/copy the lighttpd binary to /usr/sbin or edit the init.d file. If you want to edit the init.d file, change following line:
SuSE (rc.lighttpd) edit the following line:
LIGHTTPD_BIN=/usr/local/sbin/lighttpd
Red Hat/CentOS (rc.lighttpd.redhat) edit the following line:
lighttpd="/usr/local/sbin/lighttpd"
Then copy the relevant file to /etc/init.d/lighttpd and you're ready to configure it for automatic startup. For Red Hat, do the following as a superuser:
# cp doc/rc.lighttpd.redhat /etc/init.d/lighttpd # chkconfig --add lighttpd # chkconfig --level 345 lighttpd on
Creating the webserver user
You'll want an unprivileged user for lighttpd to run as. If you don't have one already, you can create one with the following commands as a superuser:
# mkdir /home/lighttpd # groupadd lighttpd # useradd -g lighttpd -d /home/lighttpd -s /bin/false lighttpd
First look at lighttpd.conf
The lighttpd.conf file is in doc/lighttpd.conf and is typically copied to /etc/lighttpd.conf where it can be edited for your site:
# cp ./doc/lighttpd.conf /etc
At a minimum you'll want to enable mod_fastcgi and set the unprivleged user and group. Add/modify the following in lighttpd.conf:
server.modules = (
"mod_rewrite",
"mod_access",
"mod_simple_vhost",
"mod_fastcgi",
"mod_accesslog"
)
server.username = "lighttpd"
server.groupname = "lighttpd"
Next, you'll need to decide whether you want to run your Catalyst app. We'll move on to configuring the Catalyst app with FastCGI before revisiting the lighttpd.conf file.
Configuring FastCGI
You'll need to have FastCGI (http://www.fastcgi.com) and Catalyst::Engine::FastCGI (http://search.cpan.org/~mramberg/Catalyst-5.65/lib/Catalyst/Engine/FastCGI.pm) installed on your system. Catalyst::Engine::FastCGI gives you several options to deploy FastCGI on your system. Here are some options:
- Stand-alone FastCGI server with sockets
- Multiple FastCGI servers with sockets
- Stand-alone FastCGI server with TCP
- Load-balanced FastCGI servers with TCP
- Static-mode with lighttpd
Running a stand-alone FastCGI server has a few advantages, the most notable being that it can easily scale out to support server farms. It can also run as under a different user id, which makes it easier to securre from other processes that run under the web server (for example your app has to be able to connect to the database, so either the uid you run under is privaleged to do that or a file readable to that uid must contain database login information - if you run under a different uid to the webserver this does not allow other webserver processes to get at your db). If you run stand-alone FastCGI servers, you'll also want to make sure they have init.d startup scripts.
The examples below all put the Catalyst app at the document root. If you wish to run your Catalyst app in a non-root location change "" to "/myapp", or your path, in the following lighttpd.conf configurations.
The examples also use a virtual host regexp that matches either www.myapp.com or myapp.com:
$HTTP["host"] =~ "^(www.)?mysite.com"
If you wish to only match one name you can change the examples to:
$HTTP["host"] == "www.mysite.com"
Stand-alone FastCGI server with sockets
To use a stand-alone FastCGI server with lighttpd you need to start the FastCGI server and configure lighttpd.conf to use the socket.
Starting the FastCGI server
Start the Catalyst FastCGI helper script. The -l option tells FastCGI what to listen for, the -n option indicates the number of processes to start and the -d option daemonizes the process.
MyApp/script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5 -d
lighttpd.conf
Include fastcgi.server in your lighttpd.conf, optionally in a virtual host.
$HTTP["host"] =~ "^(www.)?mysite.com" {
fastcgi.server = (
"" => (
"MyApp" => (
"socket" => "/tmp/myapp.socket",
"check-local" => "disable"
)
)
)
}
Multiple FastCGI servers with sockets
You may wish to start multiple FastCGI servers listening on different sockets. This is useful for having hot-swappable FastCGI processes so the FastCGI servers can be individually restarted with an updated Catalyst app without any down time. It's also useful if, on the off chance, an update causes problems. The new processes can be shut down while the site remains online with the existing ones while the new code is debugged.
Starting the FastCGI server
Start the Catalyst FastCGI helper script multiple times:
MyApp/script/myapp_fastcgi.pl -l /tmp/myapp-0.socket -n 5 -d MyApp/script/myapp_fastcgi.pl -l /tmp/myapp-1.socket -n 5 -d
lighttpd.conf
Include fastcgi.server in your lighttpd.conf, optionally in a virtual host.
$HTTP["host"] =~ "^(www.)?mysite.com" {
fastcgi.server = (
"" => (
"MyApp" => (
"socket" => "/tmp/myapp-0.socket",
"check-local" => "disable"
),
(
"socket" => "/tmp/myapp-1.socket",
"check-local" => "disable"
)
)
)
}
Stand-alone FastCGI server with TCP
To use TPC, you'll have to configure FastCGI and lighttpd.
Starting the FastCGI server
You can start the FastCGI server listening on all interfaces or just to a specific host. To listen on all interfaces use:
MyApp/script/myapp_fastcgi.pl -l 1030 /tmp/myapp.socket -n 5 -d
To listen for a specific hostname only, use:
MyApp/script/myapp_fastcgi.pl -l 10.0.0.2:1030 /tmp/myapp.socket -n 5 -d
lighttpd.conf
Edit the lighttpd.conf file as follows:
$HTTP["host"] =~ "^(www.)?mysite.com" {
fastcgi.server = (
"" => (
"MyApp" => (
"host" => "10.0.0.2",
"port" => 1030,
"check-local" => "disable"
)
)
)
}
Load-balanced FastCGI servers with TCP
One nice advantage of TCP is that it lets you call remote FastCGI servers easily. Once you have the FastCGI servers running, start up lighttpd with the following in lighttpd.conf:
$HTTP["host"] =~ "^(www.)?mysite.com" {
fastcgi.server = (
"" => (
"MyApp" => (
"host" => "10.0.0.2", "port" => 1030,
"check-local" => "disable"
),
(
"host" => "10.0.0.3", "port" => 1030,
"check-local" => "disable"
)
)
)
}
Static-mode FastCGI with lighttpd
In this mode, there's no need to run myapp_fastcgi.pl separately since lighttpd will do it for you.
$HTTP["host"] =~ "^(www.)?mysite.com" {
fastcgi.server = (
"" => (
"MyApp" => (
"check-local" => "disable",
"bin-path" => "/var/www/MyApp/script/myapp_fastcgi.pl",
"min-procs" => 2,
"max-procs" => 5,
"idle-timeout" => 20
)
)
)
}
Configuring FastCGI for Auto-Start
There are a number of ways to automatically start the fastcgi processes. One of the more popular ways is to use the OS-based init/startup system. Here is an init script for RedHat based distros contributed by Gavin Henry of Suretec Systems.
#!/bin/sh
#
# (c) Copyright 2007 - Suretec Systems Ltd.
# http://www.suretecsystems.com
#
# License: GPLv2
#
# Initial version: 11-06-2007
# Updated: 12-06-2007
#
# chkconfig: - 85 15
# description: Startup script for the fastcgi server
#
# processname: fastcgi
# config: /etc/sysconfig/fastcgi
# pidfile: /var/run/fastcgi.pid
# Source function library
. /etc/rc.d/init.d/functions
if [ -f /etc/sysconfig/fastcgi ]; then
. /etc/sysconfig/fastcgi
fi
appname="ftm_fastcgi"
prog="$appname.pl"
fastcgi="$appname.pl"
children="5"
pid="/var/run/$appname.pid"
socket="/tmp/$appname.socket"
RETVAL=0
start() {
echo -n $"Starting $prog: "
daemon $fastcgi -l $socket -n $children -p $pid -d
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
killproc -p $pid
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
return $RETVAL
}
reload() {
echo -n $"Reloading $prog: "
killproc -p $pid -HUP
RETVAL=$?
echo
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
condrestart)
if [ -f /var/lock/subsys/$prog ]; then
stop
start
fi
;;
reload)
reload
;;
status)
status -p $pid $fastcgi
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|reload|status}"
RETVAL=1
esac
exit $RETVAL
Starting lighttpd
You can use the lighttpd binary directly:
lighttpd -f /etc/lighttpd.conf
or you can use the init.d script. Red Hat/CentOS is handled by:
service lighttpd start
Further Reading
Related Entries
External Links
- lighttpd's FastCGI documentation (http://www.lighttpd.net/documentation/fastcgi.html)
- FastCGI.com (http://www.fastcgi.com)
- Catalyst::Engine::FastCGI (http://search.cpan.org/~mramberg/Catalyst-5.65/lib/Catalyst/Engine/FastCGI.pm)
