Nginx - Perl FastCGI How To
This article outlines the steps required to enable Perl cgi scripts to be ran on an Nginx web server similar to a typical Apache cgi-bin environment.
Unlike other web servers, Nginx doesn’t provide a native CGI environment for which you can execute scripts. This means that you will need to enable this feature manually. While this does mean more work, it pays of in a faster script execution environment and possible added security (depending on your implementation).
Enable execution environment for Perl scripts
- The first step is to provide a FastCGI wrapper to handle executing Perl code. This wrapper was posted by Denis S. Filimonov and like similar perl wrappers it requires the FCGI Perl module.
- For security purposes you will want to run this fastcgi wrapper script as a non privileged user.
- Now you will have to decide and edit the fastcgi-wrapper.pl script to define how you want Nginx to communicate with the fastcgi wrapper. You can configure this wrapper to listen on either TCP/IP sockets or UNIX sockets:
sub main { #-- use IP sockets $socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #-- use UNIX sockets - user running this script must have #-- write access to the '/var/run/nginx' folder!! $socket = FCGI::OpenSocket("/var/run/nginx/perl_cgi-dispatch.sock", 10);If you decide to use UNIX sockets you will need to make sure to allow write permissions for the user that this wrapper will be executed by on the directory which is designated to house the UNIX socket.
As you can see in the excerpt above, the default location of this socket is “/var/run/nginx/perl_cgi-dispatch.sock”. Once this Perl wrapper is running you should be able to see the UNIX socket it created in the /var/run/nginx/ directory.# ls -l /var/run/nginx/ srwxrwxrwx 1 nginx nginx 0 2009-02-02 14:54 perl_cgi-dispatch.sock=
- Next, as with Apache, you will need to create a cgi-bin directory for your website. Here is how you configure nginx so that it knows where your cgi-bin directory is located and to allow the execution of your Perl cgi scripts from within this directory (this is contained within a server {} block):
# /cgi-bin configuration location ~ ^/cgi-bin/.*\.cgi$ { gzip off; fastcgi_pass unix:/var/run/nginx/perl_cgi-dispatch.sock; [1]* fastcgi_param SCRIPT_FILENAME /www/blah.com$fastcgi_script_name; [2]* include fastcgi_params; [3]* }[1] The fastcgi_pass statement tells Nginx where to pass CGI requests for processing (e.g. the unix socket that the wrapper script is listening on)
[2] The fastcgi_param SCRIPT_FILENAME statement above tells Nginx that cgi scripts are located on the file system at:/www/blah.com/cgi-bin/<scriptname>.cgi
[3] Here is the contents of my fastcgi_params file:
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_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/$nginx_version; 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; # PHP only, required if PHP was built \ # with --enable-force-cgi-redirect #fastcgi_param REDIRECT_STATUS 200;
- Once this configuration has been made, make sure that you place your perl cgi scripts with .cgi extensions in the /cgi-bin directory and make sure they are executable. Restart nginx and everything should be good to go.
The link to the perl script hosted on your server no longer works.
Thanks David. It got lost in a migration, but is now replaced. I also posted a link in this article so that people can grab it directly from the ruby forum from which I obtained it at: http://www.ruby-forum.com/topic/145858
I used this particular perl-wrapper.pl script as Denis S. Filimonov has modified it to handle HTTP/CGI POST requests properly.
The script doesn’t work for me. It fails with an error like “can’t find unistd_64.ph”. I’ve verified that all the files listed in requires exist, and are readable, and have tried with Perl 5.8.8 and 5.10.1. Any idea what’s going wrong?
I had this problem when I was running slackware. Running ‘h2ph’ resolved this issue for me. You can read more here: http://www.ruby-forum.com/topic/168240
Thanks for the guide. After a lot of hassle, I now have perl working.
What do I need to do to have the fcgi listener load automatically on startup?
You could create a proper init script customized to your specific OS, but this can be time consuming depending on your requirements. Alternatively, you can simply modify rc.local by adding the desired commands. Here is a quick guide on how to do this: http://www.linux4beginners.info/?q=node/boot-shellscript-non-root