DEV Community

Cover image for Deploy A Flask App On AWS EC2
Joaquin Guardado
Joaquin Guardado

Posted on • Updated on

Deploy A Flask App On AWS EC2

Flask is a web framework for python, meaning that it provides a simple interface for dynamically generating responses to web requests. Let’s start by launching a Flask server on an Amazon Web Services EC2 instance.

1. Starting up an EC2 instance

1. Launch an EC2 instance.

  1. Log in to the AWS console here
  2. Select EC2 from AWS services.
  3. Click on Launch Instance.
  4. Select the Ubuntu Server 16.04 LTS (HVM), SSD Volume Type — ami-43a15f3e instead of the Amazon Linux. The exact versions may change with time.
  5. Click on Review and Launch.
  6. Configure the security groups as shown below. This setting allows access to port 80 (HTTP) from anywhere, and ssh access only from any IP address. 1_dCTaAa6TZLTyah4cbHFS-Q.png

2. Setting up the instance

Now that we’ve connected to the instance, it’s time to install some of the programs we’ll need.

1. Connect to the instance using ssh from the Terminal.
$ ssh -i "yourapp.pem"

2. Install the apache webserver and mod_wsgi.

$ sudo apt-get update
$ sudo apt-get install apache2
$ sudo apt-get install libapache2-mod-wsgi
Enter fullscreen mode Exit fullscreen mode

If you point your browser at your instance’s public DNS name you should see the Apache server’s “It works!” page.


3. Install Flask using the pip tool (which also needs to be installed).

$ sudo apt-get install python-pip
$ sudo pip install flask
Enter fullscreen mode Exit fullscreen mode

4. Create a directory for our Flask app.

We’ll create a directory in our home directory to work in, and link to it from the site-root defined in apache’s configuration /var/www/html by default, see /etc/apache2/sites-enabled/000-default.conf for the current value).

$ mkdir ~/flaskapp
$ sudo ln -sT ~/flaskapp /var/www/html/flaskapp
Enter fullscreen mode Exit fullscreen mode

To verify our operation is working, create a simple index.html file.

$ cd ~/flaskapp
$ echo "Hello World" > index.html
Enter fullscreen mode Exit fullscreen mode

You should now see “Hello World” displayed if you navigate to (your instance public DNS)/flaskapp in your browser.


3. Running a simple Flask app

1. Create an app.
We’ll use the simple “Hello world” example from the Flask documentation. Put the following content in a file named

from flask import Flask
app = Flask(__name__)
def hello_world():
  return 'Hello from Flask!'
if __name__ == '__main__':
Enter fullscreen mode Exit fullscreen mode

2. Create a .wsgi file to load the app.
Put the following content in a file named flaskapp.wsgi:

import sys
sys.path.insert(0, '/var/www/html/flaskapp')

from flaskapp import app as application
Enter fullscreen mode Exit fullscreen mode

3. Enable mod_wsgi.

The apache server displays HTML pages by default but to serve dynamic content from a Flask app we’ll have to make a few changes. In the apache configuration file located at /etc/apache2/sites-enabled/000-default.conf, add the following block just after the DocumentRoot /var/www/html line:


WSGIDaemonProcess flaskapp threads=5
WSGIScriptAlias / /var/www/html/flaskapp/flaskapp.wsgi

<Directory flaskapp>
    WSGIProcessGroup flaskapp
    WSGIApplicationGroup %{GLOBAL}
    Order deny,allow
    Allow from all
Enter fullscreen mode Exit fullscreen mode

4. Restart the webserver.

Use this command to restart the server with the new configuration

$ sudo service apache2 restart

5. Test configuration.

If you navigate your browser to your EC2 instance’s public DNS again, you should see the text returned by the hello_world function of our app, “Hello from Flask!”


Our server is now running and ready to crunch some data (if something isn’t working, try checking the log file in /var/log/apache2/error.log.

4. Have Flask app do work.

Now that we have a server ready to do work we’ll set up a simple service to provide letter counts from an input string.
1. Collect information from the url.
Flask allows us to route requests to functions based on the url requested. We can also get input from the url to pass into the function. Add the following to

def count_me(input_str):
    return input_str
Enter fullscreen mode Exit fullscreen mode

This count_me() function will return anything after the countme/ portion of the url. Restart the webserver to see it in action:

$ sudo service apache2 restart

2. Process information
Let’s make our count_me() function a little more interesting. Modify like so:

from collections import Counter
def count_me(input_str):
    input_counter = Counter(input_str)
    response = []
    for letter, count in input_counter.most_common():
        response.append('"{}": {}'.format(letter, count))
    return '<br>'.join(response)
Enter fullscreen mode Exit fullscreen mode

Restart the server and view the results:

$ sudo service apache2 restart

Note that it is bad practice to format HTML responses inside these functions, templates should generally be used instead.
The entire count_me() function could be written in one logical line:

return '<br>'.join('"{}": {}'.format(let, cnt)
                   for let, cnt in Counter(in_str).most_common())
Enter fullscreen mode Exit fullscreen mode

If the application throws any errors the error log can help you debug.

$ sudo tail -f /var/log/apache2/error.log

If you enjoyed this tutorial, please give me some likes. Happy coding!

Top comments (0)