Step 1 – Installing the Components from the Ubuntu Repositories

Install required package in given below

root@root:~# sudo apt update

#These will include python3-pip along with a few more packages and development tools necessary for a robust programming environment

root@root:~# sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

Step 2 – Creating  Python Virtual Environment

#installing the pythin3-venv package will install the venv module

root@root:~# sudo apt install python3-venv


#make a parent directory for our Flask project

root@root:~# mkdir ~/example
root@root:~# cd ~/example/

#Create virtual environment to store your Flask project’s Python requirements

root@root:~/example# python3 -m venv exampleenv

It will install a local copy of Python and pip into the directory. Called exampleenv with in your project directory..

Before installing applications you must activate the virtual environment Use this command for activation.

root@root:~/example# source exampleenv/bin/activate
(exampleenv) root@root:~/example#

prompt will change to indicate then you are in virtual environment it will look like this

(exampleenv) root@root:~/example#

Step 3 — Setting Up  Flask Application

you are in your virtual environment, you can install Flask and Gunicorn and get started on designing your application in here.

install wheel with the local instance of pip to ensure that our packages

(exampleenv) root@root:~/example# pip install wheel

Install Flask and Gunicorn

(exampleenv) root@root:~/example# pip install gunicorn flask

Creating a Sample App

Now you can create simple application. Flask is a microframework. It does not include many of the tools  that more full-featured frameworks might

Now create our Flask app in a single file called

(exampleenv) root@root:~/example# nano ~/example/

from flask import Flask

app = Flask(__name__)


def hello():

    return “<h1 style=’color:blue’>Hello There!</h1>”

if __name__ == “__main__”:’′)


The above configuration save and exit

You are followed the initial server setup guide, you should have a UFW firewall enabled. To test the application  you need to allow access to port 5000 in ufw

(exampleenv) root@root:~/example# sudo ufw allow 5000

Now Test your application now :

(exampleenv) root@root:~/example# python

* Serving Flask app “example” (lazy loading)

* 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 (Press CTRL+C to quit)

https://your_server_ip:5000 – Visit your ip address followed by :5000 Port number

Should see something like this


CTRL-C in your terminal window to stop the Flask development server

Creating the WSGI Entry Point

create a file that will serve as the entry point in our Application.This will tell our Gunicorn server how to interact with the application

Create file inside of Project Directory

(exampleenv) root@root:~/example# nano ~/example/

from example import app

if __name__ == “__main__”:

Save and close the above file. (from example import app) example is our flask Application Name.

Step 4 – Configuring Gunicorn

Our Application is now written with an entry point established. Now we can configuring Gunicorn. Before moving we check our Gunicorn can serve the application correctly or not.

simply passing it the name of our entry point. In our case wsgi:app

(exampleenv) root@rootr:~/example# gunicorn –bind wsgi:app

See Output like this :

[2021-03-01 09:24:49 +0100] [27840] [INFO] Starting gunicorn 20.0.4

[2021-03-01 09:24:49 +0100] [27840] [INFO] Listening at: (27840)

[2021-03-01 09:24:49 +0100] [27840] [INFO] Using worker: sync

[2021-03-01 09:24:49 +0100] [27843] [INFO] Booting worker with pid: 27843

Now visit your Server ip address with :5000

Eg : https://your_server_ip:5000 in our case our server ip address is

You can see the Application output

We are confirmed that it’s functioning properly . CTRL + C To terminate the Terminal Window.

Deactivate our Virtual Environment Using Following Command :

(exampleenv) root@root:~/example# deactivate

Python command will use the System’s Python  environment again

create the systemd service unit file.automatically start Gunicorn and serve the Flask application whenever the server boots. Create .service files with the /etc/systemd/system  Directory.

start with the [Unit] section. used to specify metadata and dependencies.put a description of our service.init system to only start this after the networking target has been reached

root@root:/etc/systemd/system# cat example.service


Description=Gunicorn instance example

####open up the [Service] section####

it will specify the user and group that we want the process to run under. give group ownership to the www-data group so that Nginx can communicate easily with the Gunicorn processes.replace the username here with your username. PATH environment variable so that the init system knows that the executables for the process are located within our virtual environment

→ Start 3 worker processes

→ Create and bind Unix Socket File.

→ example.sock within our project directory or /home Directory.. We’ll set an umask value of 007 so that the socket file is created giving access to the owner and group.while restricting other access

→ Specify the WSGI entry point file name   – (wsgi:app)






ExecStart=/root/example/exampleenv/bin/gunicorn –workers 3 –bind unix:/tmp/example.sock -m 007 wsgi:app

####[Install] section####

→ This will tell systemd  link this service to if we enable it to start at boot.



Our Main systemd Unit file Given Below


Description=Gunicorn instance example






ExecStart=/root/example/exampleenv/bin/gunicorn –workers 3 –bind unix:/home/example.sock -m 007 wsgi:app


Save and exit

#Reload Daemon Using Following Command

root@root:~/example/exampleenv/bin# systemctl daemon-reload

#start example.service file Using Following Command.

root@root:~/example/exampleenv/bin# systemctl start example.service

root@root:~/example/exampleenv/bin# systemctl status example.service

● example.service – Gunicorn instance example

Loaded: loaded (/etc/systemd/system/example.service; disabled; vendor preset: enabled)

Active: active (running) since Mon 2021-03-01 09:37:53 CET; 4s ago

Main PID: 28040 (gunicorn)

Tasks: 4 (limit: 2301)

CGroup: /system.slice/example.service

├─28040 /root/example/exampleenv/bin/python3 /root/example/exampleenv/bin/gunicorn –worker

├─28042 /root/example/exampleenv/bin/python3 /root/example/exampleenv/bin/gunicorn –worker

├─28043 /root/example/exampleenv/bin/python3 /root/example/exampleenv/bin/gunicorn –worker

└─28044 /root/example/exampleenv/bin/python3 /root/example/exampleenv/bin/gunicorn –worker

Mar 01 09:37:53 systemd[1]: Started Gunicorn instance example.

Mar 01 09:37:53 gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28040] [

Mar 01 09:37:53 gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28040] [

Mar 01 09:37:53 gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28040] [

Mar 01 09:37:53 gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28042] [

Mar 01 09:37:53 gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28043] [

Mar 01 09:37:53 gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28044] [


Step 5 — Configuring Nginx to Proxy Requests

Gunicorn application server should now be up and running configure Nginx to pass web requests to that socket.creating a new server block configuration file in Nginx’s site-available  directory – example

#install nginx package using Following Command:

root@root:~# apt-get install nginx

root@root:~# nano /etc/nginx/site-available/example

Open Server Block file and Listening On Port 80.use this block for requests for our server’s domain name. location block that matches every request. proxy_params file that specifies some general proxying parameters. pass the requests to the socket we defined using the proxy_pass

server {

listen 80;


location / {

include proxy_params;

proxy_pass https://unix:/tmp/example.sock;



Save and close the file

enable the Nginx server block configuration.Create link to sites-enabled directory

root@root:~# ln -s /etc/nginx/site-available/example /etc/nginx/site-enabled

you can test for syntax errors – using Following command

root@root:~# nginx -t

root@root:/etc/nginx/sites-available# nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful


There is no syntax Error showing.Then restart nginx process using following command

root@root:/etc#sudo systemctl restart nginx

We don’t need access through port 5000. Now we are removing that rule using following command

root@root:/etc#sudo ufw delete allow 5000

root@root:/etc#sudo ufw allow ‘Nginx Full’

now be able to navigate to your server’s domain name in your web browser.should see your application’s output

Step 6 – Securing the Application

let’s get an SSL certificate for your domain. Secure The Application using Let’s Encrypt Certificate Using.

Install Certbot’s Nginx package using apt Package

root@root:/etc/nginx/sites-available# sudo apt install python3-certbot-nginx

Certbot provides a variety of ways to obtain SSL certificates through plugins. To use the plugin using following command.

Certbot with the –nginx plugin, using -d to specify the Domain name

If you run this command First Time it  will be prompted to enter an email address and agree to the terms of service. Certbot will communicate with the Let’s Encrypt server

root@root:~# sudo certbot –nginx -d

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Plugins selected: Authenticator nginx, Installer nginx

Obtaining a new certificate

Performing the following challenges:

https-01 challenge for

Waiting for verification…

Cleaning up challenges

Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/example

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.


1: No redirect – Make no further changes to the webserver configuration.

2: Redirect – Make all requests redirect to secure HTTPS access. Choose this for

new sites, or if you’re confident your site works on HTTPS. You can undo this

change by editing your web server’s configuration.


Select the appropriate number [1-2] then [enter] (press ‘c’ to cancel): 2

Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/example

Congratulations! You have successfully enabled

You should test your configuration at:


– Congratulations! Your certificate and chain have been saved at:


Your key file has been saved at:


Your cert will expire on 2021-05-30. To obtain a new or tweaked

version of this certificate in the future, simply run certbot again

with the “certonly” option. To non-interactively renew *all* of

your certificates, run “certbot renew”

– If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let’s Encrypt:

Donating to EFF:

verify the configuration, navigate to your domain, using https://