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/
root@root:~/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 example.py
(exampleenv) root@root:~/example# nano ~/example/example.py
from flask import Flask app = Flask(__name__) @app.route(“/”) def hello(): return “<h1 style=’color:blue’>Hello There!</h1>” if __name__ == “__main__”: app.run(host=’0.0.0.0′) |
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 example.py
* 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 https://0.0.0.0:5000/ (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 fwsgi.py file inside of Project Directory
(exampleenv) root@root:~/example# nano ~/example/wsgi.py
from example import app if __name__ == “__main__”: app.run() |
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 0.0.0.0:5000 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: https://0.0.0.0:5000 (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 https://188.34.196.22:5000
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
[Unit]
Description=Gunicorn instance example
After=network.target
####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)
[Service]
User=root
Group=www-data
WorkingDirectory=/root/example
Environment=”PATH=/root/example/exampleenv/bin”
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.
[Install]
WantedBy=multi-user.target
root@root:/etc/systemd/system#
Our Main systemd Unit file Given Below
[Unit]
Description=Gunicorn instance example
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/root/example
Environment=”PATH=/root/example/exampleenv/bin”
ExecStart=/root/example/exampleenv/bin/gunicorn –workers 3 –bind unix:/home/example.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
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 fc-ansible-server.examplehosting.com systemd[1]: Started Gunicorn instance example.
Mar 01 09:37:53 fc-ansible-server.examplehosting.com gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28040] [
Mar 01 09:37:53 fc-ansible-server.examplehosting.com gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28040] [
Mar 01 09:37:53 fc-ansible-server.examplehosting.com gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28040] [
Mar 01 09:37:53 fc-ansible-server.examplehosting.com gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28042] [
Mar 01 09:37:53 fc-ansible-server.examplehosting.com gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28043] [
Mar 01 09:37:53 fc-ansible-server.examplehosting.com gunicorn[28040]: [2021-03-01 09:37:53 +0100] [28044] [
root@root:~/example/exampleenv/bin#
Step 5 — Configuring Nginx to Proxy Requests
Gunicorn application server should now be up and running Fine.now 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;
server_name avi3.examplehosting.com www.avi3.examplehosting.com;
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
root@root:/etc/nginx/sites-available#
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 avi3.examplehosting.com
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 avi3.examplehosting.com
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
https://avi3.examplehosting.com
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=avi3.examplehosting.com
IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/avi3.examplehosting.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/avi3.examplehosting.com/privkey.pem
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: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
verify the configuration, navigate to your domain, using https://