Wednesday, February 14, 2018

Deploying python Flask web app on Amazon Lightsail

Hello there,

Let me start off this with this question "What is Flask and Amazon Lightsail"?

Chances are you already know what a Flask web framework is (a light weight python web framework), so I will only give a brief on Amazon Lightsail before we deploy a simple flask app on it.

Amazon Lightsail is a Virtual Private Servers (VPS) which enables you to easily set up servers on the Amazon Web Services (AWS) cloud. It is also a fast and simple VPS hosting service from Amazon.

Alternatives to Amazon Lightsail include Heroku, DigitalOcean, Linode, Microsoft Azure etc

How to deploy Flask applications on a Virtual Private Server (VPS) running Ubuntu OS, Apache server, and WSGI

Step 1: Use your existing Amazon account or sign up for a new to subscribe for a LightSail VPS service. You can get this for as low as $5 per month.

Step 2: By now you should have you flask app fully developed and ready for deployment. My app is a simple one that doesn't require a database, so I will skip and for of database configuration.

Step 3: Now, go back to Amazon account and create an Ubuntu Server Instance. That is what we will use in this tutorial. Just click on the "Create Instance" button and complete the following...

Picking your instance image
Lightsail images are available on two platforms: Linux/Unix or Windows. Once you choose a platform, you can install a base operating system (OS), select Linux/Unix.

Select a blueprint
Select "OS only" and select "Ubuntu"

Choose your instance plan
You can start the first month for FREE.

Name your instance
Give the instance any name or leave the default name and click on "Create" buuton.

Step 4: After you have created your instance, it should be listed on you instance dashboard as seen below.

Step 5: Next is to SSH connect to the lightsail virtual private server instance by clicking on the orange square on the top right of the instance box (encircled red below). Or use PuTTy if you are on windows to SSH connect.

That is just like a normal commandline (cmd) or terminal on your local machine. Here you can do all the normal intractions you are use to on local PC/Computer. For example, we can install python modules by entering "pip install python-package" (However, recall that this is a Linux/Unix OS, so the commands will slightly be different as we shall see below...)

Step 6: To see the version of python installed on the instance, just type "Python" after the SSH connection and it will fire up the python interpreter...

Step 7: To run flask app on the instance (ubuntu OS), we have to install Apache server, WSGI (Web Server Gateway Interface), flask and other libraries used in the app. Basically run the following:-

sudo apt-get update

sudo apt-get install python-pip

sudo apt-get install python-flask

sudo apt-get install apache2

sudo apt-get install libapache2-mod-wsgi

After installing all the requirements, accessing your public IP should look like below...

Step 8: Make sure you installed all third part libraries used in your app

sudo apt-get install python-XXX

Note: replace XXX with the name of the library you are installing. If the above give you errors saying that the needed modules were not found. Try this: sudo apt-get install XXX

My app uses pandas library, so I did  sudo apt-get install python-pandas or sudo apt-get install pandas to install it.

Step 9: Put you flask app on a Github ripo, because it is easier to transfer from Github to the production server.

Alternatively, you could re create the files and folders the made up the structure of you app directly on the server using "nano" or any text editor.

But if you want to push the files from Github, then you have to install git and clone the repo as follow:-

sudo apt-get update

sudo apt-get install git

cd /var/www git clone <git-url> (replace "<git-url>" with your repo url e.g:

If this did not work deu to permission, changed the ownership of /var/www using sudo chown -R user /var/www with ‘user’ being your username.

Step 10: Navigate to the directory of the cloned app. You can do this by: cd /var/www/folder_name

Do 'ls' to list the content making sure you have all the right files and folders. The structure of the contents should be just as on the github repo.

Step 11: Create a .wsgi file which serves the Flask app. I did this using the Nano text editor. I proceeded to run the following:

nano myApp.wsgi

then type the following line in it. Remember to change "myApp" folder name and "main" file name to the specific names you are using if the names aren't the same as mine.

import sys
sys.path.insert(0, "/var/www/myApp")
from main import app as application

Hit Ctrl + X to exit Nano and enter Y when prompted to save the changes.

Note - In my case, the repo folder is at: /var/www/myApp and it has and myApp.wsgi aside from any other files (such as the templates folder and its corresponding files). That is how yours too should look like as well.

Step 12: Next is the creation of an Apache configuration file.

sudo chown -R user /etc/apache2 (replace 'user' with your username)

cd /etc/apache2/sites-available nano myApp.conf

Type the code below in the file and save it. Change the bolded parts to match that of your app.

<VirtualHost *>
WSGIScriptAlias / /var/www/myApp/myApp.wsgi
WSGIDaemonProcess hello
<Directory /var/www/myApp>
WSGIProcessGroup hello
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all

Step 13: Now, disable the default Apache site, enable your flask app, and then restart Apache for the changes to take effect. Run these commands to do this:

sudo a2dissite 000-default.conf

sudo a2ensite myApp.conf

sudo service apache2 reload

Step 14: If all the above steps went successfully, then you app should be running.

To test that everything is working, open a web browser on your local machine and type your IP address into the address. You should see your flask app being served accordingly! The app will displayed in your browser instead of the default Apache page that we saw before.

If there were errors, used the command below to see what it is:

sudo tail -f /var/log/apach2/error.log

You can fix errors by editing the corresponding file created within the VPS and reload the server.

Conclusion: I personally prefer setting a demo struct of the app then populate the files and folder using nano editor and other Linux command. Then reload the server each time I made a new change, this makes it easier for me to identify the stage where error is coming from.

Further Reading

1) How I Deployed a Flask App Using Lightsail on Amazon Web Services
2) AWS Light Sail and Flask
3) Deploying a Python Flask App on Amazon Lightsail with Dokku
4) Deploying a Flask application on AWS

No comments:

Post a Comment