How to Deploy a Flask Web Application on AWS EC2 Instance

Hello Learners…

Welcome to the blog…

Table Of Contents

  • Introduction
  • How to Deploy a Flask Web Application on AWS EC2 Instance
  • Summary
  • References

Introduction

In this tutorial, we will walk you through the process of deploying a Flask web application on an Amazon Web Services (AWS) EC2 instance. AWS EC2 provides scalable cloud computing capabilities, making it an excellent choice for hosting web applications.

By the end of this guide, you will have a fully functional Flask app running on a secure and reliable EC2 instance.

To deploy a Flask web application on an Amazon Web Services (AWS) EC2 instance, first, we have to create an AWS EC2 instance and then connect it through SSH.

If you don’t know how to do that you can follow,

Here we are using VSCode for easy-to-connect and create a Flask web application.

How to Deploy a Flask Web Application on AWS EC2 Instance

This is our AWS server on which we deploy a Flask web application.

deploy flask on aws ec2 instace

First, we have to create a Flask Web Application here we already created a Flask web app which we deploy on the AWS server.

This is the GitHub URL for the full code of the Flask web application,

Clone the GitHub Repository on the AWS EC2 instance.

First, we clone the GitHub repository of our flask web application you can use your flask web application.

If ‘git’ is not installed on the AWS EC2 then we have to install it first,

sudo yum install git
install git on aws ec2 instace using yum

And then clone the GitHub repo

git clone https://github.com/galaxyofai/flask_api_qrcode_generator

Now we create a Python virtual environment and install the required libraries using the ‘pip’.

go to the Flask Web Application directly using the ‘cd’ command,

cd flask_api_qrcode_generator

Create a Python Virtual environment

python3 -m venv venv

Activate the Python Virtual Environment

source venv/bin/activate

Install the all required libraries using the requirements.txt file

pip install -r requirements.txt

Or you can manually install all the required libraries

pip install guvicorn flask 

Here we give only two but you have to install all the libraries which are required for your Flask Web Application.

Run the Flask Web Application

We have to enable UFW firewall,To test the application, we need to allow access to port 8000

sudo ufw allow 8000

Here, app.py file is our Flask Web Application file, and we ran that file.

python3 app.py

here we use PORT 8000 because we add this port in our security group’s Inbound Rules, If you don’t know how to do that please follow the below URL,

http://your_server_ip:8000

For us: http://3.86.114.139:8000/

And we can see something below,

Flask Web Application web interface

This is the Flask Web App Interface and we can test all the functionalities from here if there are any errors or any library missing then we have to solve it first then we can go move forward.

Configuring Gunicorn

What is Gunicorn?

  • Gunicorn, short for “Green Unicorn,” is a popular production-ready WSGI (Web Server Gateway Interface) server for Python web applications. It serves as a standalone HTTP server that can run and scale Python web applications in a production environment.
  • Developers often use Gunicorn to deploy web applications developed using frameworks like Flask and Django.

Now, we have to check that Gunicorn can serve the application correctly.

To check that run the below command,

gunicorn --bind 0.0.0.0:8000 app:app

In this ‘app: app’, the first app is the name of our app.py (minus the .py extension)) file.

And we have to check our Flask Web Application

flask web app gunicorn check

Use ‘ctrl+c’ to close the running file in the terminal.

When we confirmed that it is working fine now we can move forward.

Create the systemd service unit file

Creating a systemd unit file will allow Server’s init system to automatically start Gunicorn and serve the Flask application whenever the server boots.

Create a unit file ending in .service within the /etc/systemd/system directory.

sudo nano /etc/systemd/system/qrcode.service

You can give any name to the service file.

First Add the [Unit] Section as below,

[Unit]
Description=Gunicorn instance to serve qrcode
After=network.target

Description:

  • A human-readable description of the service, providing a brief explanation of what the service does.

After:

  • The unit specifies other units that should start before this unit. The unit defines the service’s dependencies and ensures that it starts the specified units before the current service.

Next, add a [Service] section

[Service]
User=ec2-user
Group=www-data
WorkingDirectory=/home/ec2-user/flask_api_qrcode_generator/
Environment="PATH=/home/ec2-user/flask_api_qrcode_generator/venv/bin"
ExecStart=/home/ec2-user/flask_api_qrcode_generator/venv/bin/gunicorn --workers 2 --bind unix:qrcode.sock -m 007 app:app

In a systemd service file used in Linux systems, the [Service] section is a crucial part that defines how the service should be executed and managed by the systemd service manager.

This section contains specific configurations related to the behavior of the service during its execution.

Finally, add a [Install] section

[Install]
WantedBy=multi-user.target

In a systemd service file used in Linux systems, the [Install] section is an optional section that specifies how the service should be enabled and started automatically at boot time. It defines the target units where the service should install and make itself available for activation.

This is the full qrcode.service file,

[Unit]
Description=Gunicorn instance to serve qrcode
After=network.target

[Service]
User=ec2-user
Group=www-data
WorkingDirectory=/home/ec2-user/flask_api_qrcode_generator/
Environment="PATH=/home/ec2-user/flask_api_qrcode_generator/venv/bin"
ExecStart=/home/ec2-user/flask_api_qrcode_generator/venv/bin/gunicorn --workers 2 --bind unix:qrcode.sock -m 007 app:app

[Install]
WantedBy=multi-user.target

With that, our systemd service file is complete. Save and close it now.

To save first, use ‘ctrl+o’ and hit Enter and then ‘ctrl+x’ to exit.

NOTE:

  • Here we are using Group=www-data, so if a user does not belong to that group or this group does not exist then we create a Group and add a User to that group.

To add a new Group To an AWS EC2 instance

sudo groupadd www-data 

Add ec2-user to www-data group

sudo usermod -a -G www-data ec2-user

We can now start the Gunicorn service that we created

sudo systemctl start qrcode.service

and enable it so that it starts at boot:

sudo systemctl enable qrcode.service

Let’s check the status:

sudo systemctl status qrcode.service
create a service file for flask web app

Configuring Nginx

Our Gunicorn application server should now be up and running, waiting for requests on the socket file in the project directory.

Now we can configure Nginx to pass web requests to that socket by making some small additions to its configuration file.

If Nginx is not installed on AWS EC2 instance then we have to install it

sudo yum install nginx
configure nginx for deploy flask app on aws ec2 instance

Begin by creating a new server block configuration file in Nginx’s sites-available directory. Let’s call this qrcode to keep in line with the rest of the guide:

sudo nano /etc/nginx/sites-available/qrcode

Open up a server block and tell Nginx to listen on the default port 80. Let’s also tell it to use this block for requests for our server’s domain name:

server {
    listen 80;
    server_name your_domain_name;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/ec2-user/flask_api_qrcode_generator/qrcode.sock;
    }
}

To enable the Nginx server block configuration we have just created, link the file to the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/qrcode /etc/nginx/sites-enabled

With the file in that directory, we can test for syntax errors:

sudo nginx -t

If this returns without indicating any issues, restart the Nginx process to read the new configuration:

sudo systemctl restart nginx

We can then allow full access to the Nginx server:

sudo ufw allow 'Nginx Full'

You should now be able to navigate to your server’s domain name in your web browser:

http://your_domain

If you encounter any errors, try checking the following:

  • sudo less /var/log/nginx/error.log: checks the Nginx error logs.
  • sudo less /var/log/nginx/access.log: checks the Nginx access logs.
  • sudo journalctl -u nginx: checks the Nginx process logs.
  • sudo journalctl -u qrcode: checks your Flask app’s Gunicorn logs.

Summary

References

Leave a Comment