Recently I deployed a Flask App on AWS EC2. So I am writing this blog – to hopefully help you do the same.
Prerequisites
- An AWS account.
- A Flask application.
- Basic familiarity with Linux commands and SSH.
Step 1: Launch an EC2 Instance
I am assuming you have already done this and if not, There are a lot of tutorials that will help you do this. So I am just adding in some basic written steps.
- Log in to your AWS Management Console and navigate to the EC2 Dashboard.
- Click Launch Instance to create a new instance.
- Choose an Amazon Machine Image (AMI), such as Ubuntu Server.
- Select an Instance Type. The
t2.micro
type is sufficient for small applications and eligible for the AWS free tier. - Configure instance details as needed, then click Next until you reach the Configure Security Group step.
- Add rules to Allow HTTP and HTTPS traffic, and SSH access from your IP address. Do this properly, or else you will not be able to connect to the instance later by SSH.
- Review and launch the instance. Choose an existing key pair or create a new one. Download the key pair, as you’ll need it for SSH access.
Step 2: SSH into Your EC2 Instance
- Open a terminal on your local machine.
- Navigate to the directory containing your key pair file (
.pem
). - Use the SSH command to connect:
Replace /path/to/your-key-pair.pem
with the actual path to your key file, and your-ec2-public-dns with your instance’s public DNS, probably your public IP if you have not setup a domain yet.
ssh -i /path/to/your-key-pair.pem ubuntu@your-ec2-public-dns
Step 3: Prepare the Environment
- Update and upgrade your instance
sudo apt update && sudo apt upgrade -y
2. Install Python 3.9 and pip
: (I used Python 3.9 for my requirements but feel free to use the latest version)
sudo apt install python3.9 python3-pip -y
3. Install and create a virtual environment:
sudo apt install python3.9-venv -y
python3.9 -m venv venv
source venv/bin/activate
Step 4: Deploy Your Flask Application
- Transfer your Flask application to the EC2 instance using an SFTP tool like PUTTY or a Git repository.
- Activate the virtual environment and install dependencies:
source venv/bin/activate
pip install -r requirements.txt
Step 5: Install and Configure Gunicorn
In simple terms, Gunicorn serves as a middleman between your web application (written in Python) and the internet. It listens for requests from the web, passes them to your application to process, and then sends back your application’s response to the requester. Gunicorn is designed to be fast, simple to set up, and very efficient with system resources, making it a popular choice for deploying Python web applications.
- Install Gunicorn within the virtual environment:
pip install gunicorn
2. Test Gunicorn’s ability to serve your app:
gunicorn --bind 0.0.0.0:8000 yourapp:app
Replace yourapp
with the name of your Python file that creates the Flask instance (without.py
), and app
with the Flask instance variable name.
Step 6: Install and Configure Nginx
- Install Nginx:
sudo apt install nginx -y
2. Configure Nginx to proxy requests to Gunicorn. Create a new configuration file:
sudo nano /etc/nginx/sites-available/yourapp
3. Add the following configuration, then save and exit:
server {
listen 80;
server_name your-ec2-public-dns;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
4. Enable the Nginx server block:
sudo ln -s /etc/nginx/sites-available/yourapp /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
Step 7: Run Gunicorn as a Systemd Service
This step is crucial for maintaining uptime and ensuring your application is always available without manual intervention.
- Create a Gunicorn systemd service file:
sudo nano /etc/systemd/system/yourapp.service
2. Add the following configuration:
[Unit]
Description=Gunicorn instance to serve yourapp
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/path/to/your/app
Environment="PATH=/path/to/your/venv/bin"
ExecStart=/path/to/your/venv/bin/gunicorn --workers 3 --bind unix:yourapp.sock -m 007 yourapp:app
[Install]
WantedBy=multi-user.target
3. Start and enable the service:
sudo systemctl start yourapp
sudo systemctl enable yourapp
Step 8: Secure Your Application with SSL (Optional)
The application I was deploying was a simple API, so for me, SSL was not necessary. So I will not go into this for now, maybe in the future.
Conclusion
Congratulations, you’ve now deployed a Flask application on an AWS EC2 instance, using Gunicorn as the WSGI server and Nginx as a reverse proxy. In the next blog, I will discuss how you can do CI/CD for your Flask applications using Github actions.