How To Run CGI Scripts On Nginx?

Published September 23, 2024

Problem: Running CGI Scripts on Nginx

Running CGI scripts on Nginx can be difficult because of Nginx's design, which is different from other web servers. Nginx doesn't support CGI by default, so you need to set up extra configuration and modules to run CGI scripts correctly.

The Solution: Using FastCGI with Nginx

Setting Up FastCGI for Perl Scripts

To run CGI scripts on Nginx, you need to use FastCGI. This method is more efficient than traditional CGI and works well with Nginx's architecture. Here's how to set it up:

  1. Install packages: Install the required software. On CentOS, use this command:

    sudo yum install nginx fcgi-perl spawn-fcgi
  2. Configure Nginx for FastCGI: Edit your Nginx configuration file (usually at /etc/nginx/nginx.conf) to include FastCGI support. Add these lines within the server block:

    location ~ \.pl$ {
       fastcgi_pass unix:/var/run/fcgiwrap.socket;
       include fastcgi_params;
    }
  3. Create a wrapper script for your Perl CGI: Make a wrapper script to run your Perl CGI script. Save this as /usr/local/bin/perl-cgi-wrapper:

    #!/bin/sh
    exec /usr/bin/perl $1

    Set the correct permissions:

    sudo chmod +x /usr/local/bin/perl-cgi-wrapper

By following these steps, you'll have the basic setup for running Perl CGI scripts on Nginx using FastCGI. This approach allows Nginx to handle CGI requests efficiently while maintaining its performance benefits.

Tip: Optimize FastCGI Performance

To improve FastCGI performance, adjust the number of FastCGI processes based on your server resources and traffic. Add the following line to your Nginx configuration:

fastcgi_keep_conn on;

This keeps the connection between Nginx and FastCGI open, reducing overhead for multiple requests.

Configuring Nginx for FastCGI

Modifying the Nginx Configuration File

To set up Nginx for FastCGI, you need to change the Nginx configuration file. This file is often at /etc/nginx/nginx.conf. Here's how to do it:

  1. Add a location block for CGI scripts: Open the Nginx configuration file and add this block in the server section:

    location ~ \.cgi$ {
       fastcgi_pass unix:/var/run/fcgiwrap.socket;
       fastcgi_index index.cgi;
       include fastcgi_params;
    }

    This block tells Nginx to process all files ending with .cgi using FastCGI.

  2. Set up FastCGI parameters: In the same file, add or change the fastcgi_params section:

    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param QUERY_STRING    $query_string;

    These parameters pass the needed information to the FastCGI process.

  3. Set up the FastCGI socket: Add this line to the http section of your Nginx configuration:

    upstream fcgiwrap {
       server unix:/var/run/fcgiwrap.socket;
    }

    This defines the socket that Nginx will use to talk to the FastCGI process.

After making these changes, save the file and restart Nginx to apply the new settings:

sudo systemctl restart nginx

With these changes, Nginx is now set up to work with FastCGI for processing CGI scripts.

Tip: Check FastCGI Configuration

After configuring Nginx for FastCGI, it's a good idea to check if the configuration is correct. You can use the following command to test the Nginx configuration for syntax errors:

sudo nginx -t

If the configuration is correct, you'll see a message saying "nginx: configuration file /etc/nginx/nginx.conf test is successful". If there are any errors, the command will point out the specific issues in your configuration file.

Running the FastCGI Process

Starting the FastCGI Process Manually

To start the FastCGI process manually, use the spawn-fcgi command:

  1. Run this command:
sudo spawn-fcgi -u nginx -g nginx -s /var/run/fcgiwrap.socket -P /var/run/fcgiwrap.pid -F 1 -- /usr/sbin/fcgiwrap

This command starts the FastCGI process with the nginx user and group, creates a socket file, and sets the path to the fcgiwrap binary.

  1. Check if the process is running:
ps aux | grep fcgiwrap

You should see the fcgiwrap process in the output.

Automating the FastCGI Process

To start the FastCGI process automatically when your system boots, create a service file and enable it.

  1. Create a service file:

Create a new file named fcgiwrap.service in the /etc/systemd/system/ directory:

sudo nano /etc/systemd/system/fcgiwrap.service
  1. Add this content to the file:
[Unit]
Description=FastCGI wrapper
After=syslog.target network.target

[Service]
Type=forking
PIDFile=/var/run/fcgiwrap.pid
ExecStart=/usr/bin/spawn-fcgi -u nginx -g nginx -s /var/run/fcgiwrap.socket -P /var/run/fcgiwrap.pid -F 1 -- /usr/sbin/fcgiwrap
ExecStop=/bin/kill -QUIT $MAINPID

[Install]
WantedBy=multi-user.target
  1. Save the file and exit the editor.

  2. Reload the systemd daemon to recognize the new service:

sudo systemctl daemon-reload
  1. Enable the service to start on boot:
sudo systemctl enable fcgiwrap
  1. Start the service:
sudo systemctl start fcgiwrap

Now, the FastCGI process will start automatically when your system boots, and you can manage it using systemctl commands like start, stop, and restart.

Tip: Monitor FastCGI Process

To track the FastCGI process status, use the systemctl status command:

sudo systemctl status fcgiwrap

This will show if the process is active, when it started, and recent log messages. It's a good way to check if the process is running correctly or if there are issues.

Testing Your CGI Setup

To check if your CGI setup works, you can make a sample CGI script and open it in a web browser. Here's how:

  1. Create a sample CGI script:

Make a new file named test.cgi in your web server's CGI directory (often /usr/share/nginx/html/cgi-bin/):

sudo nano /usr/share/nginx/html/cgi-bin/test.cgi

Add this content to the file:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<html><body>";
print "<h1>CGI Test Script</h1>";
print "<p>If you can see this, your CGI setup is working!</p>";
print "</body></html>";

Save the file and exit the editor.

  1. Set the right permissions:

Make the script runnable:

sudo chmod +x /usr/share/nginx/html/cgi-bin/test.cgi
  1. Open the script in a web browser:

Use a web browser and enter your server's URL followed by the path to the CGI script. For example:

http://your_server_ip/cgi-bin/test.cgi

If set up right, you should see a webpage with the message "If you can see this, your CGI setup is working!"

If you have issues:

  • Check the Nginx error log for any error messages:

    sudo tail -f /var/log/nginx/error.log
  • Make sure the FastCGI process is running:

    sudo systemctl status fcgiwrap
  • Check file permissions and ownership of the CGI script.

By running this test script, you can confirm that your Nginx server is set up to handle CGI scripts using FastCGI.

Tip: Debugging CGI Scripts

If your CGI script isn't working as expected, you can add debugging information to help identify the issue. Modify your test.cgi script to include environment variables:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<html><body>";
print "<h1>CGI Test Script</h1>";
print "<p>If you can see this, your CGI setup is working!</p>";
print "<h2>Environment Variables:</h2>";
print "<ul>";
foreach $key (sort keys %ENV) {
    print "<li><strong>$key:</strong> $ENV{$key}</li>";
}
print "</ul>";
print "</body></html>";

This script will display all environment variables, which can help you understand how your CGI script is being executed and what information is available to it.