Step-by-step visual guide on deploying a Flask application on AWS EC2

Kim Huiyeon
Jun 8, 2020 · 6 min read
Image for post
Image for post
Deploy Flask Application on AWS

Flask is a framework which many people learn as their first web framework as it is simple, lightweight and easy to learn.

AWS is one of the most popular cloud services available today, providing amazing solutions for many different problems which businesses face.

In this tutorial, I will give a visual guide on how you can deploy your first Flask application on to AWS. Lets geddittt!!

Lets get it from Giphy
  1. AWS Console Account
  2. Understanding of Flask
  3. Bit of experience in Linux

Overview of the steps

  1. Create an Ubuntu EC2 on AWS
  2. SSH into Ubuntu EC2
  3. Create/Clone Flask app inside EC2
  4. Run Gunicorn WSGI server to serve the Flask Application
  5. Use systemd to manage Gunicorn
  6. Run Nginx Webserver to accept and route request to Gunicorn

(Super Secure Classified Bonus Section at the end)

Let’s get started!

Step 1: Create an Ubuntu EC2 on AWS

Of course, the first step would be to create the EC2 to deploy our application.

  1. Log in to AWS Console.
  2. Go to EC2 Section and select Ubuntu 18.4 AMI
  3. Select t2.micro if you want to stay in free tier or any other instance type you want.
  4. Press Next until Security Groups.
  5. Allow HTTP (Port 80), SSH (Port 22), HTTPS (Port 443) inbound traffic and press next.
  6. Create/Reuse Key-pair for connecting with your instance.
Image for post
Image for post
Creating EC2

Step 2: SSH into Ubuntu EC2

If you are a Windows user, please check how to connect to the EC2 with the steps specified in this link.

  1. Open a terminal
  2. Type $ ssh -i <your key name>.pem ubuntu@<Public DNS of your EC2>.
  3. If you encounter an error message, run $ chmod 400 <your key name>.pem then try Step 2 again.

4. You are in!

Image for post
Image for post
SSH into the EC2

Step 3: Create/Clone Flask application inside EC2

If you already have a flask project on a Git Repository, clone your application into the EC2.

For this article, I would create a new application.

  • Install Python Virtualenv
$ sudo apt-get update
$ sudo apt-get install python3-venv
  • Activate the new virtual environment in a new directory
// Create directory
$ mkdir helloworld
$ cd helloworld
// Create the virtual environment
$ python3 -m venv venv
// Activate the virtual environment
$ source venv/bin/activate
// Install Flask
$ pip install Flask
  • Create a Simple Flask API
$ sudo nano app.py// Add this to app.pyfrom flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello World!'

if __name__ == "__main__":
app.run()
  • Verify if it works by running python app.py
Image for post
Image for post
Create Flask API

Step 4: Run Gunicorn WSGI server to serve the Flask Application

When you “run” flask, you are actually running Werkzeug’s development WSGI server, which forward requests from a web server.

Since Werkzeug is only for development, we have to use Gunicorn, which is a production-ready WSGI server, to serve our application.

  1. Install Gunicorn using — $ pip install gunicorn
  2. Run Gunicorn — $ gunicorn -b 0.0.0.0:8000 app:app . Further modifications are possible, check out the gunicorn docs!
  3. Gunicorn is running (Ctrl + C to exit gunicorn)!
Image for post
Image for post
Run Gunicorn

Step 5: Use systemd to manage Gunicorn

Systemd is a boot manager for Linux. We are using it to restart gunicorn if the EC2 restarts or reboots for some reason.

We create a <projectname>.service file in the /etc/systemd/system folder, and specify what would happen to gunicorn when the system reboots.

We will be adding 3 parts to systemd Unit file — Unit, Service, Install

  1. Unit — This section is for description about the project and some dependencies
  2. Service — To specify user/group we want to run this service after. Also some information about the executables and the commands.
  3. Install — tells systemd at which moment during boot process this service should start.
  • With that said, create an unit file in the /etc/systemd/system directory
$ sudo nano /etc/systemd/system/helloworld.service
  • Then add this into the file.
[Unit]
Description=Gunicorn instance for a simple hello world app
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/helloworld
ExecStart=/home/ubuntu/helloworld/venv/bin/gunicorn -b localhost:8000 app:app
Restart=always
[Install]
WantedBy=multi-user.target
  • Then enable the service:
$ sudo systemctl daemon-reload
$ sudo systemctl start helloworld
$ sudo systemctl enable helloworld
  • Check if the app is running with — $ curl localhost:8000
Image for post
Image for post
Systemd for Gunicorn

Step 6: Run Nginx Webserver to accept and route request to Gunicorn

Finally, we set up Nginx as a reverse-proxy to accept the requests from the user and route it to gunicorn.

  • Install Nginx — $ sudo apt-get nginx
  • Start the Nginx service and go to the Public IP address of your EC2 on the browser to see the default nginx landing page
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
Image for post
Image for post
Setup Nginx default page
  • Edit the default file in the sites-available folder.
$ sudo nano /etc/nginx/sites-available/default
  • Add the following code at the top of the file (below the default comments)
upstream flaskhelloworld {
server 127.0.0.1:8000;
}
  • Add a proxy_pass to flaskhelloworld atlocation /
# Some code abovelocation / {
proxy_pass http://flaskhelloworld;
}
# some code below
  • Restart Nginx — $ sudo systemctl restart nginx

Tada! Our application is up!

Image for post
Image for post
Update default page to route to our Flask Application

Super Secure Classified Bonus Section

I know that you were waiting for this section.

As of now, our application is running and allows HTTP connections to it. But that’s not good. HTTP connections are not encrypted and eavesdroppers on your network can see the webpage you are visiting and data sent back and forth between.

As the title says, we would be converting our HTTP connection to a Secure HTTPS (Hypertext Transfer Protocol Secure) connection. HTTPS allows encrypted connection to your website!

There are a few things required inorder to make your application to allow HTTPS protocol.

  1. Allow Port 443 connection on your EC2’s inbound rules
  2. Domain name for your EC2 (ex: www.ilovetechfront.com)
  3. SSL Certificate

Let’s quickly go through how to do it.

Allow Port 443 connection on your EC2’s inbound rules

We navigate to the EC2’s Inbound rules on AWS Console and add a rule for HTTPS

To update a security group rule if you haven’t

  • Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/
  • In the navigation pane, choose Security Groups.
  • Select the security group attached to your EC2, choose Actions, and then choose Edit inbound rules.
  • Update the rule to allow HTTPS (443) and then choose Preview changes, Confirm.

Domain name for your EC2

You can either use:

  • Route53 service on AWS to get a domain name for your EC2 (Easier integration)
  • Get free domains from websites such as Freenom and point it to your EC2 following this article.

SSL Certificate

We need to get a SSL certificate for our application. Thankfully Certbot provides free SSL certificates.

SSH into the EC2 and follow the steps the Certbot Website Instructions for Ubuntu.

Once thats done, it’s complete!

Conclusion

That wraps up how to deploy your flask application on AWS.

Is this the only way? No. We can use Auto-Scaling groups with an Elastic Load Balancer from AWS to build a fault-resistant application. We could host using Elastic Beanstalk or even with Docker & Kubernetes. The options are endless.

Thank you for reading this blog, I hope you learnt something from this.

Tech Front

Bringing you the frontier of tech articles

Kim Huiyeon

Written by

Software Developer | Incoming Analyst at Goldman Sachs | Writer

Tech Front

Bringing you the frontier of tech articles. We post tutorials about programming, algorithms, design, cloud, data science and more. Follow us to be updated!

Kim Huiyeon

Written by

Software Developer | Incoming Analyst at Goldman Sachs | Writer

Tech Front

Bringing you the frontier of tech articles. We post tutorials about programming, algorithms, design, cloud, data science and more. Follow us to be updated!

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store