How To Serve Flask Applications with Gunicorn and Nginx

Step 1 — Installing the Components
sudo apt install nginx python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

Step 2 — Creating a Python Virtual Environment
sudo apt install python3-venv
mkdir ~/myproject
cd ~/myproject
python3 -m venv myprojectenv
source myprojectenv/bin/activate

Step 3 — Setting Up a Flask Application
pip install gunicorn flask
nano ~/myproject/myproject.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

Step 4 — Creating the WSGI Entry Point and Configuring Gunicorn
nano ~/myproject/wsgi.py

from myproject import app

if __name__ == "__main__":
    app.run()

cd ~/myproject
gunicorn –bind 0.0.0.0:5000 wsgi:app
then you should be able to open http://your_server_ip:5000

When you have confirmed that it’s functioning properly, press CTRL-C in your terminal window. We’re now done with our virtual environment, so we can deactivate it:
deactivate

Step 5 — Setup Gunicorn service
sudo nano /etc/systemd/system/myproject.service

[Unit]
Description=Gunicorn instance to serve myproject
After=network.target

[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/myproject
Environment="PATH=/home/ubuntu/myproject/myprojectenv/bin"
ExecStart=/home/ubuntu/myproject/myprojectenv/bin/gunicorn --workers 3 --bind 127.0.0.1:5000 wsgi:app

[Install]
WantedBy=multi-user.target

you can start/enable it and check its status:
sudo systemctl start myproject
sudo systemctl enable myproject
sudo systemctl status myproject

Step 6 — Configuring Nginx to Proxy Requests
sudo nano /etc/nginx/sites-available/myproject

server {
    listen 80;
    server_name ubuntu2020 www.ubuntu2020.ht.home;

    location / {
        include proxy_params;
        proxy_pass http://127.0.0.1:5000;
    }
}

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
sudo ufw allow ‘Nginx Full’

Step 7 — Securing the Application
 Certbot provides a variety of ways to obtain SSL certificates through plugins. The Nginx plugin will take care of reconfiguring Nginx and reloading the config whenever necessary.
sudo add-apt-repository ppa:certbot/certbot
sudo apt install python-certbot-nginx
sudo certbot –nginx -d your_domain -d www.your_domain

then you can open you site with SSL https://your_domain

Inspired by:
1. How to Create a Self-signed SSL Certificate for Nginx on Ubuntu
2. How to use Flask with gevent WSGI and Gunicorn

Leave a Reply

Your email address will not be published. Required fields are marked *