Overview
Most users of nginx are going to configure it to run PHP scripts via . However there are some PHP-FPM who wish to run Perl (or another language) through CGI. To do that, you will need to offload the scripting to a separate engine such as FastCGI.
FastCGI Installation
You first have to install spawn-fcgi and the FastCGI libraries.
RHEL/CentOS
If you haven’t built an applications from source on this server, you may also need some common build tools.
- yum install fcgi fcgi-devel spawn-fcgi autoconf automake make
- chkconfig spawn-fcgi on
- ln -s /usr/lib64/libfcgi.so.0 /usr/lib64/libfcgi.so
- ldconfig
Ubuntu 10.10+
- apt-get install spawn-fcgi libfcgi-dev libfcgi0ldbl
fastcgiwrap Installation
Next you have to install fcgiwrap to actually launch the CGI scripts. If you want to capture STDERR from your scripts and have it passed to the nginx error log, you will need to install fcgiwrap from source. The packages in the standard repositories are usually going to be version 1.0.x, but the STDERR option is only available in version 1.1.x, which can be installed via source from git.
- cd /usr/local/src
- git clone git://github.com/gnosek/fcgiwrap.git
- cd fcgiwrap
- autoreconf -i
- ./configure && make && make install
FastCGI Configuration
RHEL/CentOS
These directives are stored in /etc/sysconfig/spawn-fcgi:
- FCGI_SOCKET=/var/run/fcgiwrap.socket
- FCGI_PROGRAM=/usr/local/sbin/fcgiwrap
- FCGI_USER=nginx
- FCGI_GROUP=nginx
- FCGI_EXTRA_OPTIONS=”-M 0700″
- OPTIONS=”-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F 32 -P /var/run/spawn-fcgi.
- pid — $FCGI_PROGRAM -f”
It is launched using “service spawn-fcgi start”.
Ubuntu 10.10+
These directives are stored in /etc/default/fcgiwrap:
- DAEMON=”/usr/local/sbin/fcgiwrap”
- DAEMON_OPTS=”-f”
- FCGI_CHILDREN=”32″
- FCGI_SOCKET=”/var/run/fcgiwrap.socket”
- FCGI_USER=”nginx”
- FCGI_GROUP=”nginx”
- FCGI_SOCKET_OWNER=”nginx”
- FCGI_SOCKET_GROUP=”nginx”
It is launched using “service fcgiwrap start”.
FastCGI on a TCP port
FastCGI can also be configured to run on a TCP port instead of a UNIX socket. There is generally a performance hit to using a TCP port versus a Unix socket, so if nginx and the FastCGI scripts will run on the same server, a Unix socket is recommended.
RHEL/CentOS
Remove the FCGI_SOCKET directive and add/modify the following lines:
- FCGI_PORT=”9001″
- FCGI_ADDR=”127.0.0.1″
- OPTIONS=”-u $FCGI_USER -g $FCGI_GROUP -p $FCGI_PORT -a $FCGI_ADDR -S $FCGI_EXTRA_OPTIONS -F 32 -P /var/run
- /spawn-fcgi.pid — $FCGI_PROGRAM -f”
Ubuntu 10.10+
Remove the FCGI_SOCKET directive and add the following:
- FCGI_PORT=”9001″
- FCGI_ADDR=”127.0.0.1″
nginx Configuration
Make sure that the following FastCGI parameters are set in /etc/nginx/fastcgi_params:
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https if_not_empty;
# PHP only, required if PHP was built with –enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
Now, define the following in /etc/nginx/fastcgi.conf:
location
~ \.(cgi|pl)$ {
include /etc/nginx/fastcgi_params;
fastcgi_index index.cgi;
if (-f $request_filename) {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
gzip off;
}
Any virtual host that needs to have a script processed by FastCGI need to have the following directive added:
- include /etc/nginx/fastcgi.conf;
Variations
If the customer only wants one of the domains to only run CGI scripts in a specific directory (e.g., /cgi-bin), you will need to define the location” block in the “server” block, remove the “SCRIPT_FILENAME” entry from fastcgi_params, and define them in the virtual host block:
location ~ ^/cgi-bin/.*\.cgi$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /path/to/script/cgi-bin/$fastcgi_script_name;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
gzip off;
}
If all domains need that restriction then you can probably just define the “SCRIPT_FILENAME” directive in the “server” entry and modify the location block in fastcgi.conf.
In theory, this should also work for Python scripts or any other script that begins with a Shebang (“#!”)