Deployment of Web.py Applications Using uWSGI and Nginx

This post is outdated. See this post for more up-to-date directions.


It should be safe to assume that anyone remotely interested in such a topic must already have a fair understanding of what this post is about, so let’s not waste any time on introductions.

The environment is as usual a low-end VPS with Ubuntu 10.04 Lucid LTS (minimal version). First things first, if you have not already done this:

apt-get update
apt-get upgrade -y

for i in busybox-static \
         syslog-ng \
         python-setuptools \
         python-pip \
         python-software-properties \
         ; do
  apt-get install $i -yf
done

Then we install web.py (0.35 at the time of this writing) itself using pip:

pip install web.py

Next comes the servers:

add-apt-repository ppa:stevecrozz/ppa
apt-get update
apt-get install uwsgi nginx -yf

For this demonstration, we use the minimalist Hello World example from web.py tutorial as our web application. Save the following as ‘/var/www/apps/index.py’:

import web

urls = (
  '/', 'index'
)

app = web.application(urls, globals())

class index:
        def GET(self):
                return "Hello, world!"

if __name__ == "__main__": app.run()

We use the web.py built-in web server to test whether the above code is OK. In ‘/var/www/apps’ folder, type this:

python index.py

Point your browser to IP:8080 and you should be greeted with ‘Hello, world!’. Press Ctrl-C to stop the web.py built-in server.

Working upwards, next we set up uWSGI. We will be using uWSGI in VirtualHosting mode, so that more applications can be added later dynamically without having to change uWSGI configuration. Create ‘/etc/uwsgi.xml’ with the following contents


  www-data
  www-data
  
  
  127.0.0.1:9090
  1
  
  20
  128
  
  

We then set up Nginx by creating a site file in /etc/nginx/sites-enabled with the following contents:

server {
  # Change this if you want to serve your application on another port
  listen 80;

  # Replace this with your domain name
  server_name apps.example.com;

  # You can use virtual directory like '/apps/' here, but remember that
  # you should matching 'urls' defined in your web.py application file
  location / {
    include uwsgi_params;

    # This should match the 'socket' entry of your uwsgi.xml
    uwsgi_pass 127.0.0.1:9090;

    # This is the absolute path to the folder containing your application
    uwsgi_param UWSGI_CHDIR /var/www/apps;

    # This is actually not necessary for our simple application,
    # but you may need this in future
    uwsgi_param UWSGI_PYHOME /var/www/apps;

    # This is the name of your application file, minus the '.py' extension
    uwsgi_param UWSGI_SCRIPT index;
  }
}

We are almost done, but there is one last and very important step: uWSGI requires a wsgi application to be defined in the application file (index.py in our case). Just add this line to the end of index.py:

application = app.wsgifunc()

Now that everything is in place, we can (re)start Nginx and uWSGI:

service nginx restart
service uwsgi restart

Point your browser to your domain and you will now be greeted by ‘Hello, world!’ served by Nginx through uWSGI. Job done.

This entry was posted in Linux, Web and tagged , , . Bookmark the permalink.

2 Responses to Deployment of Web.py Applications Using uWSGI and Nginx

  1. jyr says:

    I have a index.py with

    import web
    
    urls = ("/", "index")
    app = web.application(urls, globals())
    
    class index:
        def GET(self):
            return 'Hello, world!'
    
    if __name__ == "__main__":
        app.run()
        application = app.wsgifunc()
    

    and return

    uWSGI Error
    wsgi application not found

    Any suggestions?

    • farter says:

      Hi,

      You are appending the ‘application = …’ line to the ‘if’ conditional statement, so it will only get executed when you run ‘python index.py’ in console, but not when uWSGI is executing index.py, hence ‘wsgi application not found’.