# Flask Web Development

This documentation will guide you through how to build and deploy a basic Python Flask application.

# Pre-Requisites

  1. VPS - You will need a Virtual Private server to build the Flask application. We recommend Digital Ocea. You can use this link to get your own VPS at a discount (opens new window). Select the latest Ubuntu operating system for your VPS.
  2. Domain -You will also need a domain where the website will be deployed. Adjust the DNS records of that domain as follows: A Record -> vps-ip-address from point 1 above. Once you have adjusted the DNS records of you domain, you can use a DNS checker tool (opens new window) to confirm that the A records indeed point to the IP address of your VPS.

# Environment Set-Up

Start by installing python3 dependencies

sudo apt update

sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

Install Virtual Environment

sudo -H pip3 install --upgrade pip

sudo -H pip3 install virtualenv

# Project Set Up

Create a project folder and navigate in to it Run this command in the location where you want to create your project folder.

mkdir whatsapp && cd  whatsapp

Create the virtual env inside the project directory

virtualenv whatsappenv

Activate the virtual environment

source whatsappenv/bin/activate

# Set up the Flask Project

Start by installing wheel

pip install wheel

Install gunicorn and Flask

pip install gunicorn flask requests

Create a file called whatsapp.py

nano whatsapp.py

Paste the following inside

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', port=5555)

Enable the Firewall for port 5555

sudo ufw allow 5555

Run the Flask application

python whatsapp.py

if all goes well you should see the following:

* Serving Flask app 'whatsapp'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5555
* Running on http://your-ip-address:5555
Press CTRL+C to quit

Create a new file

nano wsgi.py

Paste the following

from whatsapp import app

if __name__ == "__main__":
    app.run()

# Configure Gunicorn

Inside of your project folder, run the command

gunicorn --bind 0.0.0.0:5555 wsgi:app

Visit your server IP address, port 5555 and see if the application is running

http://your_server_ip:5555

Deactivate the virtual environment

deactivate

Create a systemd service unit file to run your Flask app using gunicorn

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

Paste the following inside, replacing user with your username and ensure the project directory path is as you have it on your Virtual Server

[Unit]
Description=Gunicorn instance to WhatsApp Flask Application
After=network.target

[Service]
User=user
Group=www-data
WorkingDirectory=/home/user/development/whatsapp
Environment="PATH=/home/user/development/whatsapp/whatsappenv/bin"
ExecStart=/home/user/development/whatsapp/whatsappenv/bin/gunicorn --workers 3 --bind unix:whatsapp.sock -m 007 wsgi:app

Start and Enable the project

sudo systemctl start whatsapp
sudo systemctl enable whatsapp

Check the project status

sudo systemctl status whatsapp

Output should look like:

● whatsapp.service - Gunicorn instance to WhatsApp Flask Application
     Loaded: loaded (/etc/systemd/system/whatsapp.service; static; vendor preset: enabled)
     Active: active (running) since Sat 2023-09-30 11:17:29 SAST; 31s ago
   Main PID: 2279 (gunicorn)
      Tasks: 4 (limit: 1117)
     Memory: 57.1M
     CGroup: /system.slice/whatsapp.service
             ├─2279 /home/user/development/whatsapp/whatsappenv/bin/python /home/user/development/whatsapp/whatsappenv/bin/gunicorn --workers 3 --bind unix:whatsapp.sock -m 007 wsgi:app
             ├─2291 /home/user/development/whatsapp/whatsappenv/bin/python /home/user/development/whatsapp/whatsappenv/bin/gunicorn --workers 3 --bind unix:whatsapp.sock -m 007 wsgi:app
             ├─2292 /home/user/development/whatsapp/whatsappenv/bin/python /home/user/development/whatsapp/whatsappenv/bin/gunicorn --workers 3 --bind unix:whatsapp.sock -m 007 wsgi:app
             └─2293 /home/user/development/whatsapp/whatsappenv/bin/python /home/user/development/whatsapp/whatsappenv/bin/gunicorn --workers 3 --bind unix:whatsapp.sock -m 007 wsgi:app

Sep 30 11:17:29 skolo systemd[1]: Started Gunicorn instance to WhatsApp Flask Application.

# Configure Nginx

Create a nginx file

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

Paste this in the file

server {
    listen 80;
    server_name your-domain www.your-domain;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/user/development/whatsapp/whatsapp.sock;
    }
}

Enable the server block you just created

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

Check for nginx syntax errors

sudo nginx -t

Restart Nginx

sudo systemctl restart nginx

Allow Ngix access with the firewall, while deleting 5555 port permissions.

sudo ufw delete allow 5555
sudo ufw allow 'Nginx Full'

You should be able to see your application, if you navigate to your domain.

http://your_domain

# Secure your application with certbot

Start by installing certbot

sudo apt-get update

sudo apt install python3-certbot-nginx

Install the certificate

sudo certbot --nginx -d your_domain -d www.your_domain

.