让Nginx支持CGI执行Bash,Python等脚本

  1. 1. spawn-fcgi
  2. 2. fcgi
  3. 3. fcgiwrap
  4. 4. fcgiwrap 启动脚本
  5. 5. Nginx

由于想通过页面查看VPS使用的流量,以前用的是vnstat,非常不错的一个工具,但是几个前端插件都是需要PHP环境,但是现在将博客改用Hexo后,完全静态化,只启动了一个Nginx,不想启动php-fpm,最后找到了vnstatsvg这个项目,使用CGI的方式来获取数据,最后生成svg图片来展示,满足我的需求。

那问题就来了,我后端使用的是Nginx,并非Httpd,Nginx原生不支持CGI执行,之前工作上写的很多CGI都是通过Apache Httpd来执行,以前虽然看过Nginx使用fcgi执行CGI脚本的文章,但从没实践过,这次实战一次。

spawn-fcgi

spawn-fcgi原来是Lighttpd中的模块,现在已经独立出来,由于Nginx不能直接执行外部CGI程序,因此需要依赖spawn-fcgi来执行

1
2
3
4
5
git clone [email protected]:lighttpd/spawn-fcgi.git
cd spawn-fcgi
./autogen.sh
./configure
make && make install

从github获取spawn-fcgi最新代码,然后编译安装

fcgi

安装完spawn-fcgi,还需要安装fcgi的库,我使用的系统是CentOS 6,所以直接去找了fcgi的rpm包安装,当然你也可以下载源码编译安装

如果通过rpm包安装,因为还有fcgiwrap需要依赖fcgi的库编译,因此还需要将fcgi-devel也安装

1
2
3
4
wget http://www.rpmseek.com/download/http://download.opensuse.org/repositories/home:/csbuild:/centosextra/CentOS_CentOS-6/i686/fcgi-2.4.1-2.3.i686.rpm
wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home:/csbuild:/centosextra/CentOS_CentOS-6/i686/fcgi-devel-2.4.1-2.3.i686.rpm
rpm -ivh fcgi-2.4.1-2.3.i686.rpm
rpm -ivh fcgi-devel-2.4.1-2.3.i686.rpm

fcgiwrap

最后就是安装fcgiwrap,这是一个非常轻量让Nginx执行CGI程序的wrapper

从github获取最新版编译安装

1
2
3
4
5
git clone [email protected]:gnosek/fcgiwrap.git
cd fcgiwrap
autoreconf -i
./configure
make && make install

fcgiwrap 启动脚本

为了可以方便的启动或停止fcgiwrap,使用RH或者CentOS的用户都可以使用这个方法,编写一个名为fcgiwarp的shell脚本放入/etc/init.d

脚本内容如下,需要注意你的spawn-fcgi和fcgiwrap的安装目录是否和我一致,不一致请修改,还有Nginx的执行用户是否也为www,如果不是请改为你使用的用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#! /bin/bash
### BEGIN INIT INFO
# Provides: fcgiwrap
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: FastCGI wrapper
# Description: Simple server for running CGI applications over FastCGI
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
SPAWN_FCGI="/usr/local/bin/spawn-fcgi"
DAEMON="/usr/local/sbin/fcgiwrap"
NAME="fcgiwrap"

PIDFILE="/var/run/$NAME.pid"

FCGI_SOCKET="/tmp/$NAME.socket"
FCGI_USER="www"
FCGI_GROUP="www"
FORK_NUM=5
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
start)
echo -n "Starting $NAME... "

PID=`pidof $NAME`
if [ ! -z "$PID" ]; then
echo " $NAME already running"
exit 1
fi

$SPAWN_FCGI -u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -P $PIDFILE -F $FORK_NUM -f $DAEMON

if [ "$?" != 0 ]; then
echo " failed"
exit 1
else
echo " done"
fi
;;

stop)
echo -n "Stoping $NAME... "

PID=`pidof $NAME`
if [ ! -z "$PID" ]; then
kill `pidof $NAME`
if [ "$?" != 0 ]; then
echo " failed. re-quit"
exit 1
else
rm -f $pid
echo " done"
fi
else
echo "$NAME is not running."
exit 1
fi
;;

status)
PID=`pidof $NAME`
if [ ! -z "$PID" ]; then
echo "$NAME (pid $PID) is running..."
else
echo "$NAME is stopped"
exit 0
fi
;;

restart)
$SCRIPTNAME stop
sleep 1
$SCRIPTNAME start
;;

*)
echo "Usage: $SCRIPTNAME {start|stop|restart|status}"
exit 1
;;
esac

文件新建完成后,还需要加上执行权限,并且设置为开机自启,这样就不用每次手工去启动了

1
2
3
4
chmod +x /etc/init.d/fcgiwrap
chkconfig --add fcgiwrap
chkconfig --level 2345 fcgiwrap on
/etc/init.d/fcgiwrap start

执行完上面的命令,就设置好自启,并将fcgiwrap的daemon进程启动好了

Nginx

执行CGI的环境搞好后,就差Nginx的配置了,如果将CGI的请求转发给fcgiwrap执行

1
location ~ ^/cgi-bin/.*\.(cgi|sh) {
        gzip off;
        fastcgi_pass  unix:/tmp/fcgiwrap.socket;
        fastcgi_index index.cgi;
        include fastcgi_params;
        fastcgi_param  SCRIPT_NAME        $document_root$fastcgi_script_name;
      }

我将CGI脚本放在了根目录的cgi-bin目录中,然后判断如果是.cgi或.sh结尾的文件就将请求转发给fcgiwrap执行

然后reload Nginx后就完成让Nginx执行CGI脚本的配置了,如果你还有perl或者Python脚本,只需要在Nginx配置中文件名后缀的判断加上对应后缀即可

spawn-fcgi我只启动了5个进程去执行fcgiwrap,个人使用没有啥性能问题,如果你的CGI程序访问量大,可以将进程数调高试试

声明: 除非注明,小峰网络遨游记文章均为原创,转载请以链接形式标明本文地址

本博客原创文字只代表本人某一时间内的观点或结论,与本人所在公司没有任何关系。

本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

第三方若用于商业用途的转载,须取得本人授权。

本文作者:

本文地址:http://xfeng.me/nginx-support-fcgi/

你可能还对下面文章感兴趣: