SCGI: Simple Common Gateway Interface

Introduction

The SCGI protocol is a replacement for the Common Gateway Interface (CGI) protocol. It is a standard for applications to interface with HTTP servers. It is similar to FastCGI but is designed to be easier to implement.

The is a short specification that defines the protocol. Also available is a package that implements the client and server (Apache module) sides of the protocol.

Releases

The latest release is scgi 1.15 (sig).

A beta release (Python 3 only) is available as scgi 2.0b1 (sig).

The development version of source can be downloaded using Git. The nginx web server has built-in support for the SCGI protocol.

Socket Inheritance from systemd

The 2.x series of the scgi package includes support for inheriting sockets from systemd. An example .socket file would be as follows:

    [Unit]
    Description=My App Server Socket

    [Socket]
    ListenStream=127.0.0.1:4000

    [Install]
    WantedBy=multi-user.target
    
Next, the .service file would be as follows:
    [Unit]
    Description=My App Server

    [Service]
    ExecStart=/usr/bin/python3 /path/to/app.py
    User=myuser
    EnvironmentFile=/path/to/app.env
    Restart=always
    RestartSec=5
    

Configuration of nginx

Using scgi with nginx is simple as it comes with built-in support for the protocol. To send all traffic for a HTTP server to an SCGI server, the following "location" directive will work:

    location / {
            scgi_pass 127.0.0.1:4000;
            scgi_read_timeout 900;
            include scgi_params;
    }
    

The "scgi_params" file should contain the following:

    scgi_param  SCRIPT_NAME        "";
    scgi_param  PATH_INFO          $document_uri;
    scgi_param  REQUEST_METHOD     $request_method;
    scgi_param  REQUEST_URI        $request_uri;
    scgi_param  QUERY_STRING       $query_string;
    scgi_param  CONTENT_TYPE       $content_type;

    scgi_param  DOCUMENT_URI       $document_uri;
    scgi_param  DOCUMENT_ROOT      $document_root;
    scgi_param  SCGI               1;
    scgi_param  HTTPS              $https if_not_empty;

    scgi_param  REMOTE_ADDR        $remote_addr;
    scgi_param  REMOTE_PORT        $remote_port;
    scgi_param  SERVER_PORT        $server_port;
    scgi_param  SERVER_NAME        $server_name;

    # disables chunked responses, nginx doesn't handle them
    scgi_param SERVER_PROTOCOL     "HTTP/1.0";