Website Logo
Home

Python Flask: Deploy on Linux with Gunicorn and Nginx

By Utkarsh Dubey LinkedIn Logo Last Updated: May 31, 2023

Flask is a very simple, light weight and flexible web application framework in Python. It allows creation of web applications without any specialised tools or libraries. This framework can be used to create web applications like blog, e-commerce sites or commercial website. It is simple, easy to use, easy to learn and beginner friendly as it does not require any kind of dependency.

    Pre-requisites

  • We would need a Ubuntu 20.04 or higher version sever.
  • After connecting linux server using ssh client, use below command to login with 'root' user.
    sudo su
  • Run below command to update and upgrade the linux server, which will install linux updates.
    sudo apt update && apt upgrade
  • Now create new user and provide full permissions to it. We will be using this new user suring the setup process. For covenience, I will name this user asflask-user
    adduser flask-user
    usermod -aG sudo flask-user>
  • Now, update ssh config for password authentication by setting value of 'PasswordAuthentication' property as 'yes', in sshd_config file.
    sudo vim /etc/ssh/sshd_config
    Set PasswordAuthentication yes
    systemctl restart sshd
  • At last, login with newly created user for rest of the process.
    su flask-user

Setup Application Directory

We must navigate to our home folder and create a directory for our app, where we will place our flask application code. I'll make a directory named 'flask-application' for you.

If you have placed your flask application code in github repository then clone your repository usinggit clonecommand, else, use below command to manually create simple flask application.

cd ~/
cd /flask-user
mkdir /flask-user/flask-application
sudo vim /flask-user/flask-application/my-application.py

Above command will create an empty file named 'my-application.py'. Simply paste below code in file and save using linux vim editor command(':wq!')

##### START#####

from flask import Flask
app = Flask(__name__)

# route for home location

@app.route('/')
def hello_world():
 return 'Hello World'
# main driver function
if __name__ == '__main__':
 app.run()

##### END#####

Install Python and Setup Virtual Environment

We will need to install Python application and setup a Virtual Environment for our app before we can proceed. To do so, we're moving to the application folder and installing Python Framework in conjunction with the Virtual Environment module.

cd /flask-user/flask-application
sudo apt install python3-pip
sudo apt install python3-venv

Create and Activate Virtual Environment

Now, we will create a virtual environment for our application. Virtual environment will help deploying multiple applications on same server.

sudo python3 -m venv env
source env/bin/activate

Install Dependencies

Next, we will install our applications dependencies. Since, this is a demo application, our only dependency is 'Flask' module. However, in actual application, you can have these dependencies in 'requirementx.txt' file and install them at once.

sudo pip install Flask

Install and Setup Gunicorn

Next step is to setup gunicorn server. Although, Flask has a built-in web server, but, that server is only for development environment and it is not suitable for production use. Hence, there is a need to put default server behind a real web server which will communicate with Flask server through WSGI protocol.

sudo pip install gunicorn
gunicorn --bind 0.0.0.0:5000 my-application:app
sudo apt install python3-venv
sudo ufw allow 5000
-- Comment: This will enable 5000 port on server. It is recommended to close this port on production server as this is not required.

Setup Supervisor

Next, we will setup supervisor. Supervisor is an application, which will ensure to start our application on server and keep it running all the time. It will also automatically start our application in case the server restart.

sudo apt install supervisor
sudo vim /etc/supervisor/conf.d/my-application.conf

-- Comment: Copy paste below code in above file
[program:my-application]
directory=/home/flask-user/flask=application
command=/usr/local/bin/gunicorn -w 3 my-application:app
user=flask-user
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/my-application/my-application.err.log
stdout_logfile=/var/log/my-application/my-application.out.log

Create server log directory and empty log files configured above:
sudo mkdir /var/log/my-application
sudo touch /var/log/my-application/my-application.err.log
sudo touch /var/log/my-application/my-application.out.log
sudo supervisorctl reload

Install and Setup Nginx

Nginx server is used as reverse proxy and provides an extra layer of security to applicaions. Use below commands to install nginx module. We will also delete the default configuration of server and configure our application instead.

sudo apt install nginx
sudo rm /etc/nginx/sites-enabled/default
sudo vim /etc/nginx/sites-enabled/my-application

-- Comment: Copy paste below code in above file. Please note, you have to Put public ip address of server or your domain names. Please put all domain names seperated by comma. E.g. www.example.com example.com. Also, you also have to change location of your static files in website as well. For now, we are just running hello world application and hence it does not matter much.

##### START#####
server{
 # Tune Nginx buffers #
 proxy_buffer_size 256k;
 proxy_busy_buffers_size 512k;
 proxy_buffers 8 256k;
 listen 80;
 server_name 'IP ADDRESS OF SERVER' or 'DOMAIN NAME';

 location /static/ {
    alias /home/flask-user/flask-application/;
 }

 location / {
    proxy_pass http://localhost:8000;
    include /etc/nginx/proxy_params;
    proxy_redirect off;
 }
}
##### END#####

At last, block unnecessary ports on server and restart nginx.

sudo ufw delete allow 5000-- Comment: Block 5000 port as it was only for testing the application
sudo ufw enable
sudo systemctl restart nginx

Yay !! We've setup our application.

This completes our basic python flask application setup, however there are a few extra settings we should consider for professional setup.

Few Advanced Settings

Increase Payload Size

By default, the request/response payload size is very small which we need to increase in server. We must update 'Client_MAX_body_Size' in Nginx configuration to '5M', if we want an increase of the payload size.

sudo vim /etc/nginx/nginx.conf
client_max_body_size 5M;

Enable SSL Certificate

The default configuration runs in the unsecured HTTP protocol. But we must update it to the 'https' protocol if you are going to create a professional setup.

Optional Step:If you have already bought domain name for your website, update it in server config file as guided inNginx Setupsection. Otherwise, SSL will only be enabled for ip address, instead of domain.

Detailed Steps for enabling SSL on flask application is explained in another blog. Please refer here -Secure your website for free