Tonight I decided that one of the projects I am working on would be written in Python; mainly because I hate django I went with the tornado framework. Do I need a better reason?
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.
Install nginx and tornado
yum install nginx
pip install tornado
Setup 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.
