Catalyst with Lighttpd
I spent most of last week preparing a new server to deploy a project onto a nice shiny new 1&1 Dedicated Server (oh and if you buy something from that link I get a referral bonus - yay!) All the boring stuff like bootstrapping a fresh Debian install onto the disks from a rescue image; fighting the bootloader to make it work with no indication of errors when I make a mistake since I have no physical access to the machine - you know: the ususal.
So once I'd finished those mundane tasks I had to setup the webserver. Previously I'd have gone straight for Apache 2. However I'm deploying a Catalyst application to the machine, and although Catalyst will run under mod_perl, the recommended method is to use FastCGI since it turns out to be a lot less hassle in the long run.
Aims with FastCGI
What I want from my FastCGI deployment:
- to have two seperate FastCGI managers running, so that whenever I need to upgrade the code, I can shut one down, bring it back up with the new code, then do the same for the other - thus giving me the ability to upgrade the code with no downtime (assuming of course that there are no DB changes that might require downtime etc. etc.)
- to have the static content served via the webserver, since this is what they do well
- to not have fastcgi show up anywhere in the URL.
Apache...?
Doing this with Apache+mod_fastcgi seems impossible though, since Apache's handling of FastCGI isn't briliant. To do this in Apache you basically have to create two vhosts (and optionally give them ServerName's that dont resolve externally) and then Alias / /path/to/fastCGI/N.socket.
Still with me? 'cos we're not done yet. In the main vhost for the server (i.e. www.myapp.com) you then have to create a balanced proxy like the following:
ProxyPass / balancer://myapp-cluster
<Proxy balancer://myapp-cluster>
BalanceMember http://myapp-1.internal
BalanceMember http://myapp-2.internal
Allow from all
Order Allow,Deny
</Proxy>
Complex, no? And whats worse, is that it doesn't even cope with one of the backend FastCGI servers being down - you just get a 500 page served to the user. Bad Apache! Try the other (FastCGI) server please!
The Solution - Lighttpd
After a bit of Googling, it seems like Apache just wont cope with this situation. I've been hearing good things about Lighttpd, particularly that its FastCGI support is native and much better.
The interesting bits of lighttpd config I've used:
server.moudles += (
"mod_alias",
"mod_rewrite",
"mod_redirect",
"mod_setenv",
)
Pretty self explanatory - load some of the modules we need. The rest of the config goes inside the $HTTP["host"] =~ "www.mysite.com" directive.
# Let lighttpd take care of serving that static content
alias.url = (
"/favicon.ico" => "/var/www/mysite.com/MySite/root/favicon.ico",
"/js/" => "/var/www/mysite.com/MySite/root/js/",
"/css/" => "/var/www/mysite.com/MySite/root/css/",
"/tour/" => "/var/www/mysite.com/MySite/root/tour/",
)
# rewrite-once will stop processing after the first match
url.rewrite-once = (
"^/((?:js|css|tour)/.*)" => "/$1",
"^/favicon.ico" => "/favicon.ico",
"^/(.*)" => "/fcgi/$1"
)
}
These two bits tell lighttpd to handle all the static content itself, and then forward everything else off to the /fcgi path, which is defined as follows:
fastcgi.server = (
"/fcgi" => (
( "host" => "127.0.0.1", "port" => 3010, "check-local" => "disable"),
( "host" => "127.0.0.1", "port" => 3011, "check-local" => "disable")
)
)
Fairly obvious - everything under /fcgi is handled by the FastCGI servers. Note however that this will make Catalyst think it is based at http://mysite.com/fcgi/ which it isn't, so we need to fix it:
$HTTP["url"] =~ "^/" {
setenv.add-environment = ( "SCRIPT_NAME" => "/" )
}
That does the job - Catalyst now thinks its rooted at /, and lighttpd is now handling all the static content itself.
For the completeness-sake, I've included the full config as a single block below.
$HTTP["host"] =~ "^mysite.com" {
url.redirect = ( "^/(.*)" => "http://www.mysite.com/$1" )
}
$HTTP["host"] =~ "www.mysite.com" {
# dir listings are bad
server.dir-listing = "disable"
server.errorlog = "/var/log/lighttpd/mysite.com.error.log"
accesslog.filename = "/var/log/lighttpd/mysite.com.access.log"
# Let lighttpd take care of serving that static content
alias.url = (
"/favicon.ico" => "/var/www/mysite.com/MySite/root/favicon.ico",
"/js/" => "/var/www/mysite.com/MySite/root/js/",
"/css/" => "/var/www/mysite.com/MySite/root/css/",
"/tour/" => "/var/www/mysite.com/MySite/root/tour/",
)
# rewrite-once will stop processing after the first match
url.rewrite-once = (
"^/((?:js|css|tour)/.*)" => "/$1",
"^/favicon.ico" => "/favicon.ico",
"^/(.*)" => "/fcgi/$1"
)
fastcgi.server = (
"/fcgi" => (
( "host" => "127.0.0.1", "port" => 3010, "check-local" => "disable"),
( "host" => "127.0.0.1", "port" => 3011, "check-local" => "disable")
)
)
$HTTP["url"] =~ "^/" {
setenv.add-environment = ( "SCRIPT_NAME" => "/" )
}
}
Last modified: Fri Nov 16 20:22:04 2007
Comments on Catalyst with Lighttpd | 5 comments | Post a comment