Loading...
Real Time Concepts

FastCGI (non-PHP) on nginx

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 (“#!”)

Leave a Reply

Your email address will not be published. Required fields are marked *