How to make a Scalable Python Web App using Flask, Gunicorn, NGINX on Ubuntu 14.04

August 8, 2015

This article will cover creating a Scalable Python Web Application using Flask (microframework for Python) Gunicorn (Python WSGI HTTP Server for UNIX) and NGINX on Ubuntu 14.04. There are other more full featured Python web frameworks such as Django but if you need a light weight web app or API server this stack can be a nice solution.

Step 0
Time Matters!

sudo apt-get update
sudo ntpdate
sudo apt-get install ntp

Step 1
Install PIP

sudo apt-get install python-pip

Step 2
Install Python Development

sudo apt-get install python-dev

Step 3
Install Flask

sudo pip install Flask

Step 4
Install Gunicorn

sudo pip install gunicorn

Step 5
Create a Python Flask Application

cd ~
mkdir /home/ubuntu/FLASK
cd /home/ubuntu/FLASK

from flask import Flask
app = Flask(__name__)
def hello():
    return "Hello World!"
if __name__ == "__main__":

Step 6
Create a pre-fork Gunicorn startup script to run your Flask Application

cd /home/ubuntu/FLASK

echo "Starting $NAME"
# Create the run directory if it doesn't exist
test -d $RUNDIR || mkdir -p $RUNDIR
# Start your gunicorn
exec gunicorn hello:app -b \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
chmod 755 /home/ubuntu/FLASK/

Step 7
Create a Gunicorn upstart script

cd /etc/init/
sudo vim gunicorn.conf
#Upstart Script
description "gunicorn"
respawn limit 15 5
start on runlevel [2345]
stop on runlevel [06]
env SCRIPTS_BIN=/home/ubuntu/FLASK
exec ./
end script

Step 8
Install NGINX

sudo apt-get install nginx
cd /etc/nginx/conf.d/
mkdir /home/ubuntu/www
sudo vim flask.conf

flask.conf *Make sure you change the server_name

upstream gunicorn_server {
  server localhost:8080 fail_timeout=0;
    server {
        listen       80;
	root /home/ubuntu/www;
	client_max_body_size 4G;
	keepalive_timeout 5;
        proxy_read_timeout 900;
        location / {
	try_files $uri @app;
	location @app {
      	 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header X-Real-IP	$remote_addr;
      	 proxy_set_header Host $http_host;
      	 proxy_redirect off;
      	# pass to the upstream gunicorn server mentioned above 
	 proxy_pass http://gunicorn_server;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;

Step 9
Start Gunicorn and NGINX

sudo service gunicorn start
sudo service nginx restart

More Information:

  • The formula for how many Gunicorn workers to run should be (2 x $num_cores) + 1
  • There are different types of Gunicorn workers
  • You can configure threads in Gunicorn
  • If it applies you can configure NGINX Caching to help with performance
  • Comments for “How to make a Scalable Python Web App using Flask, Gunicorn, NGINX on Ubuntu 14.04”

    1. Aco commented on July 27, 2016

      Why use Gunicorn over uWSGI. From my research uWSGI is faster and feature rich. The only benefit of Gunicorn is simplicity. Is this the reason why you chose Gunicorn over uWSGI?

    2. HD commented on October 26, 2016

      A new post to how to get maximum performance on a $5 digitalocean server for api would be nice 😀

    3. how to enable https:// in 8080 port in this tutorial ?

    Leave a Reply