How to Deploy a Website made by Python Flask on AWS EC2

Henry Wu
4 min readDec 29, 2023

--

Suppose you have already made a website locally using Python Flask and created an AWS EC2 instance. Now, you need to deploy it on the cloud so everyone online can visit.

In this article, I will use a website named “winjob” to illustrate the procedure. Here is the file structure:

STEP 1: Upload Python file to AWS EC2

Open your terminal, using the following code to upload your Python file folder to AWS EC2

rsync -av --exclude='.git/' \
--exclude='.DS_Store' \
--exclude='venv_winjob' \
--exclude='__pycache__' \
--exclude='.gitattributes' \
--exclude='.gitignore' \
--exclude='history templates' \
--exclude='history version' \
--exclude='.env' \
-e "ssh -i /Users/henrywu/MyDrive/98_Products/config/AWS_EC2_key_pair_web_winjob.pem" \
/Users/henrywu/MyDrive/99_Coding/01-Github/winjob/ \
ec2-user@ec2-35-164-114-135.us-west-2.compute.amazonaws.com:/home/ec2-user/winjob/

You need to customize the parameters above:

--exclude= part is just like .gitignore. If you don’t want to upload the files, put them here.

ssh -i part is the location of key pair you saved on your computer.

“/Users/henrywu/MyDrive/99_Coding/01-Github/winjob/ \” this part is the location of python file.

The last line is your EC2 instance address. You can get it from here on the AWS:

STEP 2: Set Up the Environment

After upload the python file, then use the SSH log in the EC2 instance.

nano ~/.ssh/config
Host ec2winjob
HostName ec2-35-164-114-135.us-west-2.compute.amazonaws.com
User ec2-user
IdentityFile /Users/henrywu/MyDrive/98_Products/config/AWS_EC2_key_pair_web_winjob.pem
AddKeysToAgent yes
UseKeychain yes

Using Ctrl+X, and then Y to save the input. Then you can use the one line code to log in EC2:

ssh ec2winjob

After you log in to EC2. It’s good practice to run Python applications within a virtual environment. This isolates your application’s dependencies from the system’s Python environment.

python3 -m venv winjob/venv_winjob
source winjob/venv_winjob/bin/activate
pip3 install -r winjob/requirements.txt

STEP 3: Set Up a Web Server

A web server like Nginx or Apache serves as a reverse proxy to handle HTTP requests and forward them to your Flask application.

sudo yum install nginx  # For Amazon Linux, CentOS, RHEL

Typically, you’ll set it up to listen on port 80 (HTTP).

sudo nano /etc/nginx/conf.d/winjob.conf

Update the server part:

server {
listen 80;
listen [::]:80;
server_name 35.164.114.135;

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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

server_name is the public IP address from your AWS EC2 instance.

Ensure your EC2 instance’s security group allows HTTP traffic (port 80).

  • Go to the EC2 dashboard in AWS Management Console.
  • Select your instance and edit its security group.
  • Allow inbound traffic on port 80 (HTTP) from your desired sources (e.g., anywhere: 0.0.0.0/0).

STEP 4: Configure a WSGI Server

Flask applications require a WSGI server in a production environment. Gunicorn is a popular choice.

pip3 install gunicorn
gunicorn -w 3 app:app

Replace the first app with the name of your Python file without the .py extension, and secondapp with the Flask app variable.

It’s normal for the terminal to keep running after you start Gunicorn, as it’s running in the foreground. To move to the next step (configuring Nginx as a reverse proxy) while keeping Gunicorn running, you can use a Process Manager.

  1. Create a Gunicorn systemd Service File: Create a new service file for Gunicorn in /etc/systemd/system/, e.g., gunicorn.service.
sudo nano /etc/systemd/system/gunicorn.service

2. Add the Following Configuration: Adjust the paths and settings according to your application setup.

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ec2-user
Group=nginx
WorkingDirectory=/home/ec2-user/winjob
ExecStart=/home/ec2-user/winjob/venv_winjob/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 >

[Install]
WantedBy=multi-user.target

Customize the WorkingDirectory and ExecStart to your own path. Then Ctrl+X, then Y, then Enter.

3. Start and Enable the Gunicorn Service:

sudo systemctl start gunicorn
sudo systemctl enable gunicorn

4. Check Status:

To make sure Gunicorn is running, you can use:

sudo systemctl status gunicorn

Once Gunicorn is running in the background or managed by a process manager, you can proceed to configure Nginx as a reverse proxy.

STEP 5: Start and Enable Web Server

Start the web server and set it to launch on boot.

sudo systemctl start nginx
sudo systemctl enable nginx

If everything goes alright, you can visit the website by the public IP address of your EC2 instance even you log out SSH:

--

--

Henry Wu
Henry Wu

Written by Henry Wu

Indie Developer/ Business Analyst/ Python/ AI/ Former Journalist/ Codewriter & Copywriter

No responses yet