How to use CGI scripts with NGINX using Fastcgi


After hours of deliberating over NGINX error logs, I have found out how to use CGI scripts with Fastcgi and NGINX. And in case anyone else is having the same problem I was, here's the solution.

After following these instructions, you will have Fastcgi and NGINX set up together, and will be able to execute any Bash/Shell, Python, Perl, or Lua script as a CGI script when placed somewhere within your document root.

Note: these instructions were written around August of 2021. If you're reading these months or years into the future, the instructions may be outdated. Read up on the current state of FastCGI online.

Instructions

For simplicity, we will be using a shell script as an example CGI script, but after following these steps you'll hopefully be able to place any .lua or .py script in your webroot and, as long as you include the language in the shebang, it will execute.

You could even use a C program as a CGI script if you have a C compiler installed which supports "running" C programs. See TCC.

These instructions are meant for Debian/Ubuntu systems. These instructions also assume that you have some familiarity with NGINX and the Linux shell prompt.

  1. Make sure you have NGINX and fcgiwrap installed.
    sudo apt-get install fcgiwrap nginx
  2. Enable NGINX and fcgiwrap.
    sudo systemctl enable --now nginx fcgiwrap fcgiwrap.socket
  3. If the file /etc/nginx/fastcgi.conf doesn't exist, create it with these contents:
    #fastcgi.conf
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;
    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  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;
  4. Add the following to the server block of the NGINX site file you want to enable CGI scripts for. By default, NGINX comes with the default site, but you can add thsi to an existing file and it will mostlikely work.
    location ~ (\.cgi|\.py|\.sh|\.pl|\.lua)$ {
                    gzip off;
                    fastcgi_pass unix:/var/run/fcgiwrap.socket;
                    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                    include fastcgi.conf ;
            }
  5. Create a CGI script (to test that the previous steps worked.) The example script is writtten in Bash and will print out some system information. Create a file called test.cgi somewhere in your document root (e.g: /var/www/html/test.cgi) and add these contents:
    #!/bin/bash
    
    echo "Content-type: text/html"
    echo ""
    
    
    cat << EOF
    <html>
    <head>
    <meta http=equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Example CGI script</title>
    </head>
    <body>
    <h1>CGI scripts work!!!</h1>
    <pre>
    EOF
    
    free
    
    cat << EOF
    </pre>
    </body>
    </html>
    EOF
    
    exit 0
  6. Make sure the script is executable
    sudo chmod +x test.cgi
  7. Test that the script worked by trying to access it from your browser. If you saved it at /var/www/html/test.cgi and nginx is running on yourwebsite.com, then you should go to yourwebsite.com/test.cgi in your browser. If everything went smoothly, you should see something similar to this:

If the above steps didn't work.... don't worry, they probably will.


Homepage Posts