nginx: Using fcgiwrap for CGI applications deployment

From the box nginx doesn’t support CGI applications deployment since CGI is very old and poor performance way to run them. But some applications still should be deployed with use of CGI (earlier, we covered setup of Nagios and OTRS with nginx). Here is another way to do that. In this case we will use fcgiwrap tool by Grzegorz Nosek. It’s written in C and should provide better performance in comparison with pure Perl wrapper we use before.

Firstly we need install it. If you use Debian or Ubuntu just install if with apt-get:

aptitude install fcgiwrap

For Fedora we’ll need compile it from sources. Download fcgiwrap from Github and unpack. Install fcgi-devel:

yum install fcgi-devel

Then run:

make install

Now you should have fcgiwrap installed in /usr/local/bin/. So, we can proceed with nginx. Here is a sample configuration. As you can see all .cgi files will be considered as CGI applications.

server {
listen 80;
server_name example.com;
root /home/web;
index index.html index.cgi;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log main;

location / {
root /home/web;
index index.html index.htm;
}

location ~ ^/cgi-bin/.*.cgi$ {
fastcgi_pass unix:/var/run/nginx/cgiwrap-dispatch.sock;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME /home/web/$fastcgi_script_name;
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 GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
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 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;
}
}

At this step we need some way to spawn our FCGI wrapper instances. For that we will use spawn-fcgi:

spawn-fcgi -u web -g web -M 0775 -F 10 -s /var/run/nginx/cgiwrap-dispatch.sock -U web -G web /usr/local/bin/fcgiwrap

To use it we will also need some kind of init.d script. Modern versions of Fedora ship with systemd, so we can use it for managing of FCGI instances pool:

[Unit]
Description=spawn-perl-fcgi

[Service]
ExecStart=/usr/bin/spawn-fcgi -u web -g web -M 0775 -F 10 -s /var/run/nginx/cgiwrap-dispatch.sock -U web -G web /usr/local/bin/fcgiwrap
Type=forking
User=root
Group=root
Restart=always

[Install]
WantedBy=multi-user.target

Put in in /lib/systemd/system/spawn-perl-fcgi.service and run:

systemctl enable spawn-perl-fcgi.service

For other systems you can use script provided in nginx wiki.

This is it.