Sunday, February 04, 2007

在 DreamHost 虚拟主机上部署 Catalyst 应用

在虚拟主机上部署 Catalyst 应用的前提是用户可以自己安装 CPAN 模块,DreamHost 提供了 shell 环境,所以就完全没问题了。

如何在非 root 环境下安装 CPAN 模块,请参考 Catalyst Wiki 中的相关文章

好,在安装完 Catalyst 之后呢,那么就万事具备,只欠东风了。
虚拟主机,Catalyst 自带的 httpd 肯定是不能用的;没有 apache 的控制权限,mod_perl 也上不了;剩下还有 cgi 和 fastcgi 方式,还用想吗?当然用 fastcgi 咯~

下面就以 fastcgi 方式为例,分享一下我的一些经验。

一、部署环境
[hostname ~]$ ls -1
MyApp/ # 项目名
example.com/ # 域名

二、apache 环境
[hostname ~]$ ls -a1 example.com
.htaccess
script -> /home/islue/MyApp/script/
static -> /home/islue/MyApp/root/static/

软链接的意义很好理解,不罗嗦了,然后来看一下 .htaccess 文件。
[hostname ~]$ cat example.com/.htaccess
AddHandler fastcgi-script .pl

RewriteEngine On

# 避免屏蔽 DreamHost 提供的 Site Statistics 功能
RewriteCond %{REQUEST_URI} ^/stats/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]

# fastcgi 工作模式
RewriteCond %{REQUEST_URI} !^/script/myapp_fastcgi.pl
RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L]

很容易理解吧,也不罗嗦了。

三、定制 myapp_fastcgi.pl
[hostname ~]$ cat MyApp/script/myapp_fastcgi.pl
...

BEGIN {
$ENV{CATALYST_ENGINE} ||= 'FastCGI';
unshift @INC, qw(
/home/islue/local/lib/perl/5.8
/home/islue/local/lib/perl/5.8.4
/home/islue/local/lib/perl5
/home/islue/local/lib/perl5/i386-linux-thread-multi
/home/islue/local/share/perl/5.8
/home/islue/local/share/perl/5.8.4
);
$SIG{'TERM'} = 'IGNORE';
}

...

我原以为,修改过了 .bashrc 之后,应该不需要再用 use lib 了,但是数次实践下来,不在 myapp_fastcgi.pl 里声明用户的 lib 还真不行。要是哪位知道这里的道道,记得告诉我啊。

至于为什么要 IGNORE TERM,故事是这样的,很久很久以前,世界和平,大家都过着男耕女织的生活,不用在意什么,MyApp 也能跑得欢快。

突然有一天,电闪雷鸣,大雨瓢泼,MyApp 就再也跑不起来了,访问站点能看到的只有 Internal Server (500) 错误,翻开史册,书上如是说:
[Mon Jan 29 06:13:13 2007] [error] [client 210.151.136.180] FastCGI: comm with (dynamic) server "/home/islue/example.com/script/myapp_fastcgi.pl" aborted: (first read) idle timeout (60 sec)
[Mon Jan 29 06:13:13 2007] [error] [client 210.151.136.180] FastCGI: incomplete headers (0 bytes) received from server "/home/islue/example.com/script/myapp_fastcgi.pl"

在无数次 ps 之后,总算看到 myapp_fastcgi.pl 的身影一闪而过。是他杀,我惊醒!真相只有一个,下面公布凶手的自白书。
Dreamhost regularly kills off sleeping processes with a proc watch script. This will kill your dispatch.fcgi processes, leading to Error 500s from time to time. You'll need to make dispatch.fcgi ignore all TERM requests by changing how it responds to them.

说笑啦,上面这段是 DreamHost 客服给我的回复。IGNORE TERM 之后,世界又太平了。

四、应用启动方式

启动应用的方法就是访问站点。如果需要重启,杀掉所有 myapp_fastcgi.pl 即可,如果 IGNORE TERM 了的话,需要 kill -9。

1 comment:

nowazhu said...

要超级谢谢你歪,偶也在dreamhost上跑成功了~~