Learn How To Setup Gunicorn to Serve Python Web Applications

March 9, 2019

Table of Contents

    In this article, we will setup a VPS to serve Python web applications with Gunicorn and Nginx as a reverse proxy. We use Nginx as a reverse proxy instead of serving with Gunicorn directly to prevent DoS attacks on Gunicorn. Using Nginx also results in better performance (with proxy buffering), and results in more requests being handled.

    Getting started

    This tutorial assumes that you already have a VM with Ubuntu 14.04 or newer installed, updated, and secured.

    • Our Nginx instance will run on HTTP port 80 (but you can easily upgrade to HTTPS).
    • Our example Python app will listen on port 8080. This port will be closed on iptables to prevent remote access.
    • This tutorial should run on other distros with minimal changes.

    Install pip, virtualenv:

    apt-get install python-pip python-virtualenv

    Close port 8080. Gunicorn will be reachable only by Nginx.

    iptables -A INPUT -p tcp --destination-port 8080 -j DROP

    Create a new folder and configure our application. We’ll be using the Flask framework.

    mkdir /var/www-folder/
    cd /var/www-folder/
    virtualenv exampleapp
    source exampleapp/bin/activate
    cd exampleapp
    pip install gunicorn
    pip install flask

    Create the application file.

    nano myapplication.py 

    Paste the following inside:

    from flask import Flask
    app = Flask(__name__)
    def hello_world():
        return 'Hello, IT Web Services!'

    This would produce a simple page saying “Hello, IT Web Services!” when someone accesses the page. Now, start Gunicorn. Replace x with 2 times the number of your VM’s CPU cores.

    gunicorn -w x myapplication:app &

    Install Nginx and configure the reverse proxy.

    apt-get install nginx
    nano /etc/nginx/sites-enabled/default

    Search for the location / { line and replace the content inside the brackets with the following content.

    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:8000/;

    This configuration instructs Nginx to forward some information (HTTP protocol, remote IP address) along with the actual request to the Gunicorn server. Reload Nginx.

    service nginx reload

    At this point, your Gunicorn application has been properly configured. You can access it using a web browser at http://YOUR_INSTANCE_IP/.

    Need help?

    Do you need help setting up this on your own service?
    Please contact us and we’ll provide you the best possible quote!