Nginx

How to use Nginx with Flask.

Python is a great, easy-to-learn, and all-powerful programming language, and with frameworks such as Django and Flask, we can use it to create full-fledged web applications. Once we create a web application using libraries and frameworks such as Flask, we need to host it on a server and expose it to the public. This tutorial discusses how to host your web application on a server running Nginx using Gunicorn. Before we get started with Flask and Gunicorn, ensure that you meet the following requirements:

  • A server with SSH access
  • Nginx web server running on the server (installation covered)
  • Python
  • You are a sudo user.

Setting up the Server

Let us now start setting the server environment that we shall use to host our server. This tutorial uses the Ubuntu Server. Start by updating the repositories and installing Python3 and Pip.

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install python3 python3-pip -y

Next, we need to create a directory to store the project.

sudo mkdir /var/www/application
cd /var/www/application

Change directory ownership and permissions:

sudo chown -R www-data:www-data /var/www/application/

Next, install the packages using apt (flask and Gunicorn)

sudo apt-get install python3-flask python3-gunicorn

Let us now proceed to initialize a flask application. Start by creating the main.py—holds the application—and wsgi.py, which will get the application running.

sudo touch main.py wsgi.py

Edit the main.py file and set up your Flask application and all the routes. Since this tutorial is not a Flask guide, we will set up a basic route and a hello world message.

from flask import Flask
 
app = Flask(__name__)
@app.route("/")
def home():
    return "<h1>Nginx & Gunicorn</h1>"

Edit the wsgi.py file and add the code to import app, and run as:

from main import app
 
if __name__ == "__main__":
    app.run(debug=True)

Finally, test if it is up and running by calling flask as:

$ flask run
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Try accessing the application on http://localhost:5000.

Setting Up Gunicorn

Once our application is successfully running, we can use Gunicorn to test the application using the commands:

$ sudo gunicorn --workers 5 wsgi:app
[2021-03-19 09:19:34 +0000] [14047] [INFO] Starting gunicorn 20.0.4
[2021-03-19 09:19:34 +0000] [14047] [INFO] Listening at: http://127.0.0.1:8000 (14047)
[2021-03-19 09:19:34 +0000] [14047] [INFO] Using worker: sync
[2021-03-19 09:19:34 +0000] [14049] [INFO] Booting worker with pid: 14049
[2021-03-19 09:19:34 +0000] [14050] [INFO] Booting worker with pid: 14050
[2021-03-19 09:19:34 +0000] [14051] [INFO] Booting worker with pid: 14051
[2021-03-19 09:19:34 +0000] [14052] [INFO] Booting worker with pid: 14052
[2021-03-19 09:19:35 +0000] [14053] [INFO] Booting worker with pid: 14053

The above commands runs the flask application using Gunicorn using the specified number of workers. We then call the file wsgi:app, which is the file and instance of the application to run.

Once you have the application running using Gunicorn, press CTRL + C to stop the server and setup Nginx.

Use the commands below to install and run Nginx.

sudo apt-get install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

The next step is to edit the Nginx config in the sites-enabled directory and add the server block. Consider the following configuration. Change the application to the name of your project.

sudo nano /etc/nginx/sites-available/application.conf
server {
        listen 80;
        server_name application;
 
        access_log /var/log/nginx/application.access.log;
        error_log /var/log/nginx/appliation.error.log;
 
        location / {
                include proxy_params;
                proxy_pass http://unix:/var/www/application/application.sock;
        }
}

Proceed to create a link to the site-enabled directory to enable the website.

sudo ln -s /etc/nginx/sites-available/application.conf /etc/nginx/sites-enabled/

Now restart the Nginx service as:

sudo systemctl restart nginx

Next, we need to create a systemd unit file to serve the application.

sudo nano /etc/systemd/system/application.service
[Unit]
Description=application.service - A Flask application run with Gunicorn.
After=network.target
 
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/application/
ExecStart=/usr/bin/gunicorn --workers 3 --bind unix:/var/www/application.sock wsgi:app
 
[Install]
WantedBy=multi-user.target

Finally, save the unit file, then enable and reload the daemon.

sudo systemctl restart application.service
sudo systemctl daemon-reload

Now you can access the application using the IP address or the address specified in the nginx config file. You may need to add it to the host’s file.

curl http://application
HTTP/1.1 200 OK
Server: Werkzeug/0.16.1 Python/3.8.5)
Date: Fri, 19 Mar 2021 10:00:39 GMT
Content-Type: text/html
Content-Length: 25
Last-Modified: Fri, 19 Mar 2021 09:22:47 GMT

Conclusion

This tutorial went over how to set up a Python Flask application and serve it over Nginx using Gunicorn. Consider the individual documentation to learn more about the services discussed in this tutorial.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list