How to deploy a Flask application in Linux

I recently migrated this blog from Hugo to Flask. I have been learning Flask, so I wanted to practice by setting this up. After the website was done in my machine, I wanted to deploy it in my server. I had to follow these steps:

Install required Python packages and Nginx

sudo apt update && sudo apt upgrade
sudo apt install python3 python3-pip python3-venv nginx

Create the virtual environment and install the project requirements

python3 -m venv env
source env/bin/activate
pip install -r requirements.txt

Install Gunicorn (the wsgi server)

pip install gunicorn
gunicorn -w 4 -b 127.0.0.1:8000 app:app

This assumes that you have an app.py file in your code and that you have something like this in your code:

app = Flask(__name__)
if __name__ == '__main__':
    app.run(debug=True)

If gunicorn starts well, you can kill it with Ctrl+C

Create a systemd service for Gunicorn

sudo vim /etc/systemd/system/yourapp.service

Define your service:

[Unit]
Description=Gunicorn instance for my website
After=network.target

[Service]
User=yourusername
Group=www-data
WorkingDirectory=/path/to/your/project
Environment="PATH=/path/to/your/project/env/bin"
ExecStart=/path/to/your/project/env/bin/gunicorn --workers 4 --bind unix:/path/to/your/project/yourapp.sock app:app

[Install]
WantedBy=multi-user.target

Start and enable Gunicorn

sudo systemctl daemon-reload
sudo systemctl start yourapp
sudo systemctl enable yourapp
sudo systemctl status yourapp

Set up Nginx configuration

sudo vim /etc/nginx/sites-available/yourapp
server {
    listen 80;
    server_name yourdomain.com;

    location / {
        include proxy_params;
        proxy_pass http://unix:/path/to/your/project/yourapp.sock;
    }
}

And then enable the site and restart Nginx:

sudo ln -s /etc/nginx/sites-available/yourapp /etc/nginx/sites-enabled
sudo nginx -t # Check for errors
sudo systemctl restart nginx

Set up a firewall, if needed

sudo ufw allow 'Nginx Full'
sudo ufw enable

Secure with SSL (HTTPS)

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

And auto-renew SSL

sudo certbot renew --dry-run

Restart everything

To finish the set-up, restart everything:

sudo systemctl restart nginx
sudo systemctl restart yourapp

And that would be all! Go to yourdomain.com and the website should be up and running!

#tech