Skip to content

Instantly share code, notes, and snippets.

@ewheeler
Created October 4, 2011 22:12
Show Gist options
  • Save ewheeler/1262989 to your computer and use it in GitHub Desktop.
Save ewheeler/1262989 to your computer and use it in GitHub Desktop.
flask + tornado + nginx + supervisord
# create stub, then run flask app in tornado on port 5000 (perhaps with supervisord config below http://supervisord.org/index.html)
#!/usr/bin/env python
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from myflaskapp import app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()
# edit /etc/nginx/sites-available/default (or mysite.conf)
# add server info (like below, see http://groups.google.com/group/python-tornado/browse_thread/thread/18afe7d87f4d2616?pli=1)
# sudo /etc/init.d/nginx restart
server {
listen 80 default;
server_name mydomain.com;
# path for access log
access_log /var/log/nginx/mydomain.com.access.log;
# define locations here to catch css, javascripts,
# and other statics BEFORE trying to proxy to tornado
location /static/ {
if ($query_string) {
expires max;
}
try_files $uri /directory/containing/static/$uri;
}
# then define root location handler
location / {
try_files $uri @tornado;
}
# proxy to tornado running on port 5000
# to run more than one tornado, see https://gist.github.com/791971
location @tornado {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:5000;
}
}
# example supervisord.conf for running tornado
[unix_http_server]
file=/tmp/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
[program:tornado-5000]
command=/myflaskapp/app.py ; the program (relative uses PATH, can take args)
autostart=true ; start at supervisord start (default: true)
autorestart=true ; retstart at unexpected quit (default: true)
stdout_logfile=/var/log/supervisord/tornado-stdout.log ; stdout log path, NONE for none; default AUTO
stderr_logfile=/var/log/supervisord/tornado-stderr.log ; stderr log path, NONE for none; default AUTO
@AndreiD
Copy link

AndreiD commented Sep 3, 2014

Maybe this helps someone.

For the nginx config, your settings didn't worked correctly for serving static files.... after some digging I found out that you have to add root in the server. here's my config. tested and working

server {
listen 80 default;
server_name domain.com;
server_name www.domain.com;

    access_log  /var/log/nginx/domain.com.access.log;

    root /home/your_flask_project;


    location /static/ {
           expires max;
           add_header Last-Modified $sent_http_Expires;
           alias /home/your_flask_project/app/static/;
    }


    location / {
            try_files $uri @tornado;
    }

    location @tornado {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass       http://127.0.0.1:5000;
    }

}

2nd. I use this for tornado. to start it on more threads.

http_server = HTTPServer(WSGIContainer(app))
http_server.bind(1337)
http_server.start(0)
ioloop = tornado.ioloop.IOLoop().instance()
autoreload.start(ioloop)
ioloop.start()

With apache benchmark using this configuration for tornado, I get 4x better results on a i3 laptop showing 4 cores in htop. If you have just 1 core VPS this might not work compared to the standard one.

@aetherwu
Copy link

@AndreiD 's solution for static files worked for me.
May I ask for a way to enable tornado https behind the nginx?
Thanks...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment