DIY · Open Source · TechIt

Simple CGI Web App Testing setup with Python-CGI and NGINX/uWSGI 

This week I needed to set up a very simple web app.

I’ve ended up looking at Python to wire up some cgi scripting to an otherwise static html/js “website”.

For the #poc I installed the Debian network install ISO into a virtual box VM…

Installing NGINX…

apt-get install nginx

service nginx status
service nginx start

and tested it quickly with the browser.

All good.

I did make one customisation to the config, changing the default root path to one in my home folder editing
/etc/nginx/sites-available/default
and changing
root /usr/share/nginx/www;
to
root /home/me/public-html;

NGINX Configuration…

For Python/Cgi support in NGINX I encountered some discussion here http://raspberrywebserver.com/cgiscripting/setting-up-nginx-and-uwsgi-for-cgi-scripting.html

I’m quite happy to report it covers nearly everything, but I avoided the custom UWSGI build/install mentioned and tried to stick to the apt packages & work around the issues the author encountered.

First copied the NGINX config aside and then opened PICO to edit it with my changes:

cd /etc/nginx/sites-available
cp default default-cgi
pico default-cgi

Edited the location “/” and added the location “/cgi-bin” per the above article:

...

# root /usr/share/nginx/www;
root /home/me/public-html;
index index.html index.htm;

# Make site accessible from http://localhost/
server_name localhost;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html /cgi-bin/pyindex.py?q=$uri;

# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}

# nginx has no cgi bits, so need a helper app (fastcgi, uWSGI, etc)
# added for uWSGI which has many modes/plugins but we'll leverage just cgi
location /cgi-bin {
include uwsgi_params;

# tells uWSGI to handle requests for this location as CGI scripts.
uwsgi_modifier1 9;

uwsgi_pass 127.0.0.1:9000;
}

....

Cleaned up the NGINX config to be used

cd ../sites-enabled/
rm default
ln -s ../sites-available/default-cgi

and a restart to pick it all up
service nginx restart

Testing http://myserver.lan/ is still fine,

but http://myserver.lan/cgi-bin/hello.py returns a “Bad Gateway” message. 😦

I need to get to the UWSGI pieces.

Installing CGI Support…

This is where the article method caused some issues for me.

I kept getting the “Bad Gateway” error.

less /var/log/nginx/error.log

revealed that

"upstream prematurely closed connection while reading response header from upstream"

Looking at

less /var/log/uwsgi/app/uwsgi_config.log

showed something about the modifier wasn’t liked,

-- unavailable modifier requested: 9 --.

At this stage I spent some time trying various alternatives to the config at  /etc/uwsgi/apps-available/uwsgi_config.ini,

including having gotten  apt-get install uwsgi-plugin-python (don’t bother) and tried uwsgi configurations with  plugins=python, but seemingly this is a *bad idea* and one may get it working eventually but with quite a bit of frustration and hair loss.

In the end – per http://uwsgi-docs.readthedocs.org/en/latest/CGI.html – I noted specifically

that “The CGI plugin is by default not built in to the core” so with a little

apt-cache search uwsgi

I noticed a cgi plugin for uwsgi and got it instead.

I had success then with the below install

apt-get install uwsgi
apt-get install uwsgi-plugin-cgi

service uwsgi status
service uwsgi start

Configuring python-cgi …

edit the uwsgi configurations

cd /etc/uwsgi/apps-available/
pico uwsgi_config.ini

paste in

[uwsgi]
plugins = cgi
socket = 127.0.0.1:9000
module = pyindex
cgi = /home/me/public-html
cgi-allowed-ext = .py
cgi-helper = .py = python

then linking it up to be enabled and restart

cd ../apps-enabled/
ln -s ../apps-available/uwsgi_config.ini
service uwsgi restart

Again watching these files

cat /var/log/nginx/access.log
cat /var/log/nginx/error.log
cat /var/log/uwsgi/app/uwsgi_config.log

I had “not-found” errors (due to my configured cgi path having “cgi-bin” appended) and unauthorised errors because of permissions, note my configuration changes to the cgi folder from the article.

My python hello.py script now lives under /home/me/public-html/cgi-bin so I also had to set the file to +x, and give the cgi-bin folder and its contents a group of www-data (via chgrp)

chgrp www-data /home/me/public-html/cgi-bin/
chgrp www-data /home/me/public-html/cgi-bin/*
chmod g+x /home/me/public-html/cgi-bin/*

restarted everything one last time just in case

service uwsgi restart
service nginx restart

and w00t!!!! I got a python-cgi response in my browser 😀

Have fun and many thanks if you contributed in content or comment to those linked articles/docs.

2 thoughts on “Simple CGI Web App Testing setup with Python-CGI and NGINX/uWSGI 

Leave a comment