We have recently bought a VPS for İTÜ24, the online newsletter of Istanbul Technical University. The server is running on Ubuntu Server 12.04 operating system. Due to limited memory resources and performance concerns, we preferred to setup nginx as web server.
Our server will serve several web pages and applications developed in various programming languages, such as PHP, Python, Ruby (on Rails). Currently, we have one Python application, which is using Flask framework.
How we run Flask application with nginx, step by step…
Step 0: Requirements
We work on a virtual Python environment, using virtualenv, and install Python packages with pip. Install these by typing:
sudo apt-get install python-virtualenv python-pip
Create a virtual environment and activate it.
virtualenv hello source hello/bin/activate
Notice, your prompt is now prefixed with the name of the virtual environment.
Step 1: The Application
After installing Flask with pip, you can save the following code as “hello.py” and run it.
pip install Flask
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Hello world!" if __name__ == '__main__': app.run()
Flask has a built-in web server that allows you to run your application. However, it is not scalable and production ready. On the other hand, there is gunicorn which is a production ready Python WSGI server that also provides scalability.
Step 2: Gunicorn
pip install gunicorn
In order to make our application to work with gunicorn, we have to add two lines to it:
from flask import Flask from werkzeug.contrib.fixers import ProxyFix app = Flask(__name__) @app.route('/') def hello(): return "Hello world!" app.wsgi_app = ProxyFix(app.wsgi_app) if __name__ == '__main__': app.run()
Notice the 2nd and 9th lines. Now we can serve our application with Gunicorn.
gunicorn hello:app
“hello” is the name of the file (without extension). And “app” is the name of the Flask object. You can find more info about configuration of gunicorn on their web pages.
Step 3: Nginx
Create new server configuration and save the file in /etc/nginx/sites-available/hello.conf.
server { listen 80; server_name hello.itu24.com; root /path/to/hello; access_log /path/to/hello/logs/access.log; error_log /path/to/hello/logs/error.log; location / { proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; if (!-f $request_filename) { proxy_pass http://127.0.0.1:8000; break; } } }
Enable new configuration by creating a symbolic link in sites-enabled directory.
sudo ln -s /etc/nginx/sites-available/hello.conf /etc/nginx/sites-enabled/
Check configuration for errors:
nginx -t
If your configuration is ok, you can reload nginx and access your application now.
sudo service nginx reload
Update 2012/09/07: In order to start gunicorn automatically when the system reboots, check my new blog post!
Update 2012/10/05: You had better not use if statements in Nginx configurations, because if is evil! See this comment