How to Deploy a Flask application on Amazon Lightsail, using Apache2, WSGI and Flask. cover image

How to Deploy a Flask application on Amazon Lightsail, using Apache2, WSGI and Flask.

By Gavin Marsh

software

Development Stack

Introduction

Amazon Lightsail is intended for developing quickly and cheaply. In this tutorial I will walk through how to set up an Amazon Lightsail instance with Apache2, WSGI and Flask development stack for deploying a Flask web-application.

What the Red Means

Changes that the user needs to make or customise will be in red in this tutorial! The rest will mostly be copy-and-pastable. (shout out to Digital Ocean //link to digital ocean// for this tutorial format).

Step One - Create an AWS account

Head over to https:aws.amazon.com/ and set up an AWS account if you do not already have one, this account will also be used for your Lightsail instances.

Once you have setup your AWS account, log in and head over to there Lightsail //https://aws.amazon.com/lightsail// website.

Step Two - Create an Ubuntu 16.04 Lightsail Instance

Click on the 'Create Instance' tab and select 'Linux/Unix' tab, then underneath click 'OS Only' then select 'Ubuntu 16.04 LTS'.

Choose your Instance plan, for this tutorial we will use the cheapest $3.50 per month plan.

Then finally scroll down the page and rename your Instance to 'FlaskLightsailDepoloyment' and click on the 'Create instance' button.

Step Three - create static IP to publicly access your Lightsail instance.

Click the 'Home' button and then click on the 'Networking' tab and then click on the 'Create static IP' tab.

Scroll to the bottom of the page, rename your static IP and click the 'Create' button.

Make a note of your new static IP address and attach it to your Lightsail instance if not done so already (found on the Networking tab and by clicking on the three orange dots on the static IP address box, this will take you to a management screen where you can attach the IP to your Lightsail instance).

Step Four - Allow Fire Wall access to public internet traffic.

Click the 'Home' button and then click on the small three orange dots next to wear it says FlaskLightsailInstance. This will open up a dropdown menu. Select 'Manage' from this drop down menu.

From the management screen you will be able to see your Public and Private Ip addresses, scroll down the page and you will see your Fire Wall section. Set your Fire Wall preferences for testing by inputing the below settings. This will allow all internet traffic to reach your Lightsail instance.

Step Five - Setting up SSH

Finally, we will install our development stack by remotely logging onto our Lightsail instance via SSH. To do this we need to download our SSH private keypair.

Click the 'Account' Tab at the top of the page. Then click on the 'SSH Keys' tab. If you have not done so already create a new key pair and rename it 'MyKeyPair', then click the download button to download to your local downloads folder.

After you download the MyKeyPair.pem file, you will want to store your key in a secure location. If you lose your key, you won't be able to access your instance. If someone else gets access to your key, they will be able to access your instance.

Windows users: It is recommend saving your key pair in your user directory in a sub-directory called .ssh (ex. C:\user{yourusername}.ssh\MyKeyPair.pem).

Tip: You can't use Windows Explorer to create a folder with a name that begins with a period unless you also end the folder name with a period. After you enter the name (.ssh.), the final period is removed automatically.

Mac/Linux users: It is recommend saving your key pair in the .ssh sub-directory from your home directory (ex. ~/.ssh/MyKeyPair.pem).

On MacOS, the key pair is downloaded to your Downloads directory by default. To move the key pair into the .ssh sub-directory, enter the following command in a terminal window: mv ~/Downloads/MyKeyPair.pem ~/.ssh/MyKeyPair.pem

Open a terminal window. Use the chmod command to make sure your private key file is not publicly viewable by entering the following command to restrict permissions to your private SSH key:

chmod 400 ~/.ssh/MyKeyPair.pem

You do not need to do this every time you connect to you instance, you only need to set this once per SSH key that you have.

In your local terminal, Use SSH to connect to your instance.

ssh -i {full path of your .pem file} lightsail-server-name@{instance IP address}

Example: ssh -i ~/.ssh/MyKeyPair.pem ubuntu@ip-127-25-13-2@3.8.237.222

You'll see a response similar to the following:

The authenticity of host 'lightsail-198-51-100-1.compute-1.amazonaws.com (10.254.142.33)' can't be established. RSA key fingerprint is 1f:51:ae:28:df:63:e9:d8:cf:38:5d:87:. Are you sure you want to continue connecting (yes/no)?

Type yes and press enter. You'll see a response similar to the following:

Warning: Permanently added 'lightsail-198-51-100-1.compute-1.amazonaws.com' (RSA) to the list of known hosts.

You should then see the welcome screen for your instance and you are now connected to your Amazon Lightsail Ubuntu 16.04 virtual machine in the cloud.

Step Six - Install Apache2

Update the apt package.

sudo apt update

upgrade the package.

sudo apt upgrade

Install the upgrades.

sudo apt-get update

Update the local language.

sudo locale-gen "en_GB.UTF-8"

Install the main apache2 files.

sudo apt-get install apache2

Update apache2 to dev.

sudo apt-get install apache2-dev

Edit Apache2 configuration file with your server IP address.

sudo nano /etc/apache2/apache2.conf

Add the following line of text at the bottom of the apache2.conf file and save the file by pressing CTL-X.

ServerName <IP address of server> Example: ServerName 3.8.237.222

Step Seven - Install Python3.7.1

Update apt install package.

sudo apt update

Download PPA python package.

sudo add-apt-repository ppa:deadsnakes/ppa

Update apt package.

sudo apt update

Install python3.7.1.

sudo apt install python3.7

Step Eight - Install WSGI.

Download WSGI tar file.

https://github.com/GrahamDumpleton/mod_wsgi/archive/4.6.4.tar.gz

Open up a second Terminal window and use scp to transfer downloaded WSGI tar file from your local machine to your remote Amazon Lightsail instance.

scp -i ~/.ssh/MyKeyPair.pem {full path of your mod_wsgi-4.6.4.tar.gz file} {instance IP address}:~

Example:

scp -i ~/.ssh/MyKeyPair.pem /Users/gavinmarsh/Downloads/mod_wsgi-4.6.4.tar.gz 3.8.237.222:~:~

Go back to your terminal window connected to your Lightsail instance then: Unpact the tar file. tar xvfz mod_wsgi-4.6.4.tar.gz

Remove original tar.

rm -r mod_wsgi-4.6.4.tar.gz

Move into unpacked WSGI folder.

cd mod_wsgi-4.6.4

Install Python2.7-dev.

sudo apt-get install python2.7-dev

Install python-pip (incase you are missing any Python2.7 dev files.

sudo apt install python-pip

Configure the WSGI file.

./configure --with-python3=/usr/bin/python3.5.2 && make && sudo make install

Create a new apache2 mods WSGI configuration file.

sudo nano /etc/apache2/mods-available/mod_wsgi.so.load

Add the below text to the file, save and close.

LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so

Install Liapache2.

sudo apt-get install libapache2-mod-wsgi-py3

Restart the apache2 server.

sudo /etc/init.d/apache2 restart

Step Nine - Prepare server for new 'Hello World' FlaskApp.

Deactivate default apache2 website. sudo a2dissite 000-default.conf

Change directory into Apache2, sites-enabled folder.

cd /etc/apache2/sites-enabled

Remove apache2 default configuration file.

rm 000-default.conf

Step Ten - Create a Flask application

Change directory into Ubuntu's standard Website directory. cd /var/www

Remove apache2 standard html folder.

sudo rm -R html

Make a new directory call FlaskApp to store your application files.

sudo mkdir FlaskApp

Change directory into this new folder.

cd FlaskApp

Make a new diectory called FlaskApp to store your application source code.

sudo mkdir FlaskApp

Change directory into this new folder.

cd FlaskApp

Make two new directories one called static and another called templates.

sudo mkdir static templates

Create a new .py file called init.py and open that file.

sudo nano __init__.py

Enter the following text into the file, save and close.

from flask import Flask app = Flask(name)

@app.route("/") def hello(): return "Hello World! from Flask"

if name == "main": app.run()

Tip: sometimes nano doesn’t recognise the double quote symbol so delete and retype them until the string text turns green.

Install Virtualenv.

pip3 install virtualenv

Create a new python virtual environment called 'venv'

sudo virtualenv venv

Activate this new environment.

source venv/bin/activate

Install the Flask framework.

sudo pip3 install Flask

Create a new apache2 configuration file called FlaskApp.conf.

sudo nano /etc/apache2/sites-available/FlaskApp.conf

Enter the below text into the file then save and close.

Listen 80
<VirtualHost \*:80>
    ServerName 3.8.237.222
    ServerAdmin admin@mywebsite.com
    WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi
    <Directory /var/www/FlaskApp/FlaskApp/>
        Order allow,deny
        Allow from all
    </Directory>
    Alias /static /var/www/FlaskApp/FlaskApp/static
    <Directory /var/www/FlaskApp/FlaskApp/static/>
        Order allow,deny
        Allow from all
        </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    LogLevel info
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Enable your new FlaskApp configuration.

sudo a2ensite FlaskApp

Change directory into FlaskApp parent directory.

cd /var/www/FlaskApp

Create a new wsgi file called flaskapp.wsgi.

sudo nano flaskapp.wsgi

Enter the below text into the file, save and close.

!/usr/bin/python</h1>

import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")

from FlaskApp import app as application
application.secret_key = 'Add your secret key'

Restart the Apache2 server.

sudo /etc/init.d/apache2 restart

Check everything is running correctly

Use curl to print website to terminal

curl 3.8.237.222/

You should see an output of "Hello World! from Flask" in your terminal window.

If not you can trouble shoot buy printing apache2's error logs to your terminal window using the tail command.

sudo tail -10 /var/log/apache2/error.log

Finally, open up a new browser window and enter your public Lightsail IP address.

http://3.8.237.222/

If all has gone well, you should see "Hello World! from Flask" in your browser window.

Summary

I had always not bothered looking at AWS for my MVP (minimum viable product) development work as I found it too expensive. Amazons Lightsail offering however is very cheap to set up just $3.5 per month for there cheapest instance (VPS) and it is ideal for quick prototyping work as it has a feature called 'Snapshot' which allows you to take a snapshot of your server image and then transfer it across with just a few clicks to a larger AWS EC2 server set up for future horizontal and vertical scaling if the project grows or moves to production, this feature was what prompted me to move my python Flask deployments across to Amazon.

Published on March 29, 2019.

Get my best monthly insights on sales + software

Can I send you monthly useful & interesting finds about personal growth, enterprise-sales, software & making stuff that matters? I'll also link to any new articles or projects.

No spam. Unsubscribe anytime.