Setting up Tornado w/ Nginx

Tonight I decided that one of the start ups I am working on would be written in Python so mainly because I hate django I went with the tornado framework.

Setting this up I went with nginx proxying to tornado over port 3000, googling there wasn’t much documentation so I decided since sharing is caring that I would document how this was accomplished:

Installing nginx and tornado framework

yum install nginx
pip install tornado

Setting up init script for tornado

Open your favorite text editor and create a init script at /etc/init.d/tornado with the following contents.

#!/bin/sh
workdir=/home/xqa/public
start() {
    cd $workdir
    /usr/bin/python -m tornado.autoreload server.py &
    echo "Server started."
}
stop() {
    pid=`ps -ef | grep '[p]ython -m tornado.autoreload server.py' | awk '{ print $2 }'`
     echo $pid
     kill $pid
     sleep 2
     echo "Server killed."
 }
 case "$1" in
   start)
     start
     ;;
   stop)
     stop
     ;;
   restart)
     stop
     start
     ;;
   *)
     echo "Usage: /etc/init.d/tornado {start|stop|restart}"
     exit 1
 esac
 exit 0

Configure nginx

Now we just need to setup nginx so it can proxy to our tornado service; open up /etc/nginx/nginx.conf in your favorite editor and use something similar to the following configuration making tweaks as necessary.

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
    worker_connections 1024;
    use epoll;
}
http {
     # Enumerate all the Tornado servers here
     upstream frontends {
         server 127.0.0.1:3000;
     }
     include /etc/nginx/mime.types;
     default_type application/octet-stream;
     access_log /var/log/nginx/access.log;
     keepalive_timeout 65;
     proxy_read_timeout 200;
     sendfile on;
     tcp_nopush on;
     tcp_nodelay on;
     gzip on;
     gzip_min_length 1000;
     gzip_proxied any;
     gzip_types text/plain text/html text/css text/xml
                application/x-javascript application/xml
                application/atom+xml text/javascript;
     # Only retry if there was a communication error, not a timeout
     # on the Tornado server (to avoid propagating "queries of death"
     # to all frontends)
     proxy_next_upstream error;
     server {
         listen 80;
         # Allow file uploads
         client_max_body_size 50M;
         location ^~ /static/ {
             root /home/xqa/public;
             if ($query_string) {
                 expires max;
             }
         }
         location = /favicon.ico {
             rewrite (.*) /static/favicon.ico;
         }
         location = /robots.txt {
             rewrite (.*) /static/robots.txt;
         }
         location / {
             proxy_pass_header Server;
             proxy_set_header Host $http_host;
             proxy_redirect off;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Scheme $scheme;
             proxy_pass http://frontends;
         }
     }
 }

This handles proxying port 80 to port 3000 so normal users can just go to the domain and see the tornado app.

Write a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.