- 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 upgrade -y
sudo apt-get install python3 python3-pip -y
Next, we need to create a directory to store the project.
cd /var/www/application
Change directory ownership and permissions:
Next, install the packages using apt (flask and 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.
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.
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:
if __name__ == "__main__":
app.run(debug=True)
Finally, test if it is up and running by calling flask as:
* 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:
[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 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.
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.
Now restart the Nginx service as:
Next, we need to create a systemd unit file to serve the application.
[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 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.
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.