Open In App

How to Deploy Python WSGI Apps Using Gunicorn HTTP Server Behind Nginx

Improve
Improve
Like Article
Like
Save
Share
Report

This article describes how to deploy a Python WSGI application using Gunicorn and Nginx. Before proceeding with the tutorial, it’s a good idea to first familiarize yourself with the terms WSGI, Gunicorn, and Nginx. Web Server Gateway Interface or WSGI is a specification that describes how a web server (in this case Nginx) interacts with a Python web application/framework.

Though some Python web frameworks have a built-in development server for running web applications, it is not recommended to use it for production. Therefore, you need a server like Gunicorn, a robust and secure application server that connects to and runs Python application instances via a WSGI interface.

Nginx is a web server used with Gunicorn as a reverse proxy that accepts incoming HTTP requests from clients and redirects them to Gunicorn.

Prerequisites

For deploying a web application you need a server with a public IP address, we will be using a Debian virtual machine deployed on Azure.

Installing required packages

Following the Linux command will install Python3, pip package installer, and Nginx on the Debian machine,

sudo apt install python3 python3-pip nginx 
How to Deploy Python WSGI Apps Using Gunicorn HTTP Server Behind Nginx

 

Setup a development environment for your project

First, let us configure the development environment, this step can be skipped but it is always a good idea to use a dedicated development environment for each project, this can be achieved using a python virtual environment. To create one just run the following commands:

mkdir python_web_app; cd python_web_app
How to Deploy Python WSGI Apps Using Gunicorn HTTP Server Behind Nginx

 

This will create a dedicated folder for the project, you can name it anything you want and cd (change directory) to go into your newly created directory then run the following command that will create a virtual environment for your project.

python3 -m venv venv
ls

 

Now let’s activate the virtual environment and start using it.

source venv/bin/activate
pip install gunicorn

 

Create a WSGI App and configure it for deployment

Now that the environment is ready, let’s create a WGI app in Python,

nano app.py

This will create an empty file now paste the following code in there,

def application(env, start_response):
  status = "200 OK"
  response_headers = [('Content-Type', 'text/plain; charset=utf-8')]
  start_response(status, response_headers)
  message = "GeeksforGeeks is a best coding platform.".encode('utf-8')
  return [message]
How to Deploy Python WSGI Apps Using Gunicorn HTTP Server Behind Nginx

 

The above code is a very simple WSGI App that we are going to deploy in this article.

Using Gunicorn to serve the project

Now run the following command,

gunicorn app:application --bind 0.0.0.0:8000

 

How to Deploy Python WSGI Apps Using Gunicorn HTTP Server Behind Nginx

 

The above command will allow the WSGI app to start taking client requests on localhost port 8000.

Creating system Socket and Service files for Gunicorn

Now that you’ve tested that Gunicorn with your Django application, you should implement a more robust way of starting and stopping the application server. To accomplish this, we will create systemd service and socket files, by running the following commands.

sudo nano /etc/systemd/system/gunicorn.socket

This will open the system socket file for Gunicorn with sudo privileges, and add the following stuff to the file, which creates a [Unit] section to describe the socket, a [Socket] section to define the socket location, and a [Install] section to make sure the socket is created at the right time, once done just save and close the file.

[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target

 

sudo nano /etc/systemd/system/gunicorn.service

Now, let’s create and open a systemd service file for Gunicorn (the filename should match the socket filename) and add the following content to the file. It should look something like this.

 

As you can see It contains 3 sections :

  • [Unit]: This is used to specify metadata and dependencies.
  • [Service]: it specifies the user and group that you want the process to run under, also giving group ownership to the www-data group so that Nginx can communicate with Gunicorn.  
  • [Install]: This will tell systemd what to link this service to if you enable it to start at boot.

Enabling and checking socket and service files for Gunicorn.

The following commands will start running the Gunicorn socket service and will enable it to start automatically on boot.

sudo systemctl enable gunicorn.socket
sudo systemctl start gunicorn.socket

Output:

 

Check the status of the Gunicorn process to find out whether it was able to start

sudo systemctl status gunicorn

Output:

 

If something goes wrong you can see the logs for the Gunicorn process by running the following command:

sudo journalctl -u gunicorn.socket

Configure Nginx proxy

Let’s configure Nginx to work along gunicorn and handle HTTP requests for this we need to create a server block,

sudo nano /etc/nginx/sites-available/python_web_app

 

server {
  listen 80;
  server_name server_domain_or_IP;
  location = /favicon.ico { access_log off; log_not_found off; }
  location /static/ {
      root <project path>;
  }
  location / {
      include proxy_params;
      proxy_pass http://unix:/run/gunicorn.sock;
  }
}

Here you can find all the configurations that can be done in Nginx, once finished run the following command,

sudo ln -s /etc/nginx/sites-available/python_web_app /etc/nginx/sites-enabled

It is going to enable the file by linking it to the site-enabled directory.

All done now just run these commands to test the Nginx file for any errors etc.

sudo nginx -t
sudo systemctl restart nginx
How to Deploy Python WSGI Apps Using Gunicorn HTTP Server Behind Nginx

 

A Python WSGI App is deployed successfully.


Last Updated : 21 Nov, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads