Compute Engine Google Cloud

How To Install Flask on Ubuntu 18.04 with uWSGI, Nginx on Google Cloud

Introduction

How To Install Flask on Ubuntu 18.04 with uWSGI, Nginx on Google Cloud

Flask is an open source micro framework for Python.

In this guide, I will demonstrate how to install and configure Flask, uWSGI and Nginx on Ubuntu 18.04 LTS.

Prerequisites

  1. Your Compute Engine Instance running, see the Setting up Compute Engine Instance.
  2. Domain name is pointed to your virtual machine.
  3. For setting up Cloud DNS, see the Setting up Google Cloud DNS for your domain.

Choose Best Hosting for your Business

PlatformReviewsPricing
Siteground★★★★★$3.95
Kinsta – Google Cloud★★★★★$30

Install required packages

SSH to your Compute Engine instance and begin typing the following commands to start installing Flask

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

Creating a Python Virtual Environment for Flask

sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv
mkdir ~/myprojectdir
cd ~/myprojectdir
virtualenv myprojectenv

Activate the virtual environment by typing

source myprojectenv/bin/activate

Your prompt should change to indicate that you are now operating within a Python virtual environment. It will look something like this: (myprojectenv)[email protected]:~/myprojectdir$

Setup Flask

pip install wheel
pip install uwsgi flask

Create a Sample Flask App

sudo nano ~/myprojectdir/myproject.py

Paste the following

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
    return "<h1 style='color:blue;text-align:center;margin:200px auto;border:1px solid blue;padding:10px 20px;width:300px;'>Welcome to Flask!</h1>"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

Hit Ctrl+X followed by Y to save the file

deactivate

Create Socket and Service files for uWSGI

sudo nano ~/myprojectdir/wsgi.py

Now import the Flask instance from your application

from myproject import app

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

Create a uWSGI configuration file for long-term usage

sudo nano ~/myprojectdir/myproject.ini
[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

Now create the systemd service unit file to automatically start uWSGI and serve the Flask application whenever the instance boots.

sudo nano /etc/systemd/system/myproject.service
[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=username
Group=username
WorkingDirectory=/home/username/myprojectdir
Environment="PATH=/home/username/myprojectdir/myprojectenv/bin"
ExecStart=/home/username/myprojectdir/myprojectenv/bin/uwsgi --ini myproject.ini

[Install]
WantedBy=multi-user.target

Start and enable your configuration

sudo systemctl start myproject
sudo systemctl enable myproject
sudo systemctl status myproject
uWSGI status

NGINX Proxy Pass to uWSGI and setup HTTPS

Edit your nginx.conf and replace user www-data with user username

Create a new Nginx configuration for your website in the sites-available directory

sudo nano /etc/nginx/sites-available/yourdomainname.com

Copy and paste the following configuration, ensure that you change the server_name, error_log to match your domain name. Hit CTRL+X followed by Y to save the changes.

server {
    listen 80;
    listen [::]:80;

    server_name yourdomainname.com www.yourdomainname.com;

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/username/myprojectdir/myproject.sock;
    }
}

To enable this newly created website configuration, symlink the file that you just created into the sites-enabled directory.

sudo ln -s /etc/nginx/sites-available/yourdomainname.com /etc/nginx/sites-enabled/yourdomainname.com

Check your configuration and restart Nginx for the changes to take effect

sudo nginx -t
sudo service nginx restart

Now visit your domain name in your web browser, you can view the Flask Sample page you have created.

Flask Installed

Create SSL certificate and enable HTTP/2

HTTPS
HTTPS is a protocol for secure communication between a server (instance) and a client (web browser). Due to the introduction of Let’s Encrypt, which provides free SSL certificates, HTTPS are adopted by everyone and also provides trust to your audiences.

HTTP/2
HTTP/2 is the latest version of the HTTP protocol and can provide a significant improvement to the load time of your sites. There really is no reason not to enable HTTP/2, the only requirement is that the site must use HTTPS.

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

Now we have installed Certbot by Let’s Encrypt for Ubuntu 18.04, run this command to receive your certificates.

sudo certbot --nginx certonly

Enter your email and agree to the terms and conditions, then you will receive the list of domains you need to generate SSL certificate.

To select all domains simply hit Enter

The Certbot client will automatically generate the new certificate for your domain. Now we need to update the Nginx config.

Redirect HTTP Traffic to HTTPS with www in Nginx

Open your site’s Nginx configuration file add replace everything with the following. Replacing the file path with the one you received when obtaining the SSL certificate. The ssl_certificate directive should point to your fullchain.pem file, and the ssl_certificate_key directive should point to your privkey.pem file.

server {
    listen [::]:80;
    listen 80;

    server_name yourdomainname.com www.yourdomainname.com;
    
    # redirect http to https www
    return 301 https://yourdomainname.com$request_uri;
}

server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;

    server_name www.yourdomainname.com;

    ssl_certificate /etc/letsencrypt/live/yourdomainname.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomainname.com/privkey.pem;

    root /home/username/myprojectdir;

    # redirect https non-www to https www
    return 301 https://yourdomainname.com$request_uri;
}

server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;

    server_name yourdomainname.com;

    ssl_certificate /etc/letsencrypt/live/yourdomainname.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomainname.com/privkey.pem;

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        include uwsgi_params;
        uwsgi_pass unix:/home/username/myprojectdir/myproject.sock;

        add_header Content-Security-Policy "img-src * 'self' data: blob: https:; default-src 'self' https://*.googleapis.com https://*.googletagmanager.com https://*.google-analytics.com https://s.ytimg.com https://www.youtube.com https://www.yourdomainname.com https://*.googleapis.com https://*.gstatic.com https://*.w.org data: 'unsafe-inline' 'unsafe-eval';" always;
add_header X-Xss-Protection "1; mode=block" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Access-Control-Allow-Origin "https://www.yourdomainname.com";
        add_header Referrer-Policy "origin-when-cross-origin" always;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
    }
}

The http2 value is all that is needed to enable the HTTP/2 protocol.

Hit CTRL+X followed by Y to save the changes.

Check your configuration and restart Nginx for the changes to take effect.

sudo nginx -t
sudo service nginx restart

Renewing SSL Certificate

Certificates provided by Let’s Encrypt are valid for 90 days only, so you need to renew them often. Now you set up a cronjob to check for the certificate which is due to expire in next 30 days and renew it automatically.

sudo crontab -e

Add this line at the end of the file

0 0,12 * * * certbot renew >/dev/null 2>&1

Hit CTRL+X followed by Y to save the changes.

This cronjob will attempt to check for renewing the certificate twice daily.

Enjoy your Flask installation on Ubuntu 18.04 LTS with uWSGI, Nginx and HTTPS on Google Cloud

Cloudbooklet builds a large collection of Linux based guides and tutorials on Cloud platforms like Google Cloud, AWS, Azure, DigitalOcean and more

Write A Comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

If you find this helpful? Support me!
Buy me a coffee Donation Please buy me a coffee