Skip to main content

How to Deploy a REST API on AWS EC2 with Python and Docker

·3 mins

In this tutorial I will walk through the steps you need to take to deploy a simple Flask API to AWS. Before we begin make sure you have python and docker installed on your local machine as well as an AWS account.

Create Source Files #

Start by creating a new directory and inside the directory create a new .gitignore file. If you would like to use gig a CLI tool to create your .gitignores automatically enter go install github.com/hayitsdavid/gig.

mkdir my-api && cd my-api
gig new python docker

Set up python needs.

python -m venv .venv
source .venv/bin/activate
pip install Flask
pip freeze > requirement.txt

Main file #

Below is a simple Flask API that retutrns ‘Hello, World!’ when requested.

# app.py
from flask import Flask

app = Flask(__name__)

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

Dockerfile #

Create a new file called Dockerfile and save the below into it.

# Set base image (host OS)
FROM python:3.10-slim-buster

# Set the working directory in the container
WORKDIR /app

# Copy the dependencies file to the working directory
COPY requirements.txt requirements.txt

# Install any dependencies
RUN pip3 install -r requirements.txt

# Copy the content of the local src directory to the working directory
COPY . .

# Specify the command to run on container start
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]

Now let’s build the image and run it! To build the imate we simply need to run the docker build -t <some-name> command.

Note that Flask will automatically connect to port 5000 and we want it to go to 80. So when using docker run --publish we can specifity this by entering two numbers newPort:oldPort and then the name of the image.

docker build -t my-api .
docker run --publish 80:5000 my-api

Check out localhost:80/ and you should see ‘Hello, World!’

Create AWS EC2 Instance #

Login to https://aws.amazon.com/ec2/ and click orange Launch Instance button.

When inside you want to generate a new key-pair and name it whatever your project is. This will generate a corresponding .pem file.

Set security for:

  • HTTPS 0.0.0.0/0
  • SSH your.ip + “/32” for fire wall

SSH Into EC2 #

Move your .pem file to ~./ssh and run chmod 400 <name>.pem beforehand.

# login in to ec2
ssh -i <some-name>.pem ec2-user@<dns>.amazonaws.com

# update
sudo yum update

# install dependencies
sudo amazon-linux-extras install docker
sudo service docker start
sudo usermod -a -G docker ec2-user
exit

(Optional) Add RSA key to server #

Though optional, this will save you from typing ssh -i <some>.pem before evey command interacting with the instance.

If you don’ have one type ssh-keygen -t rsa -b 4096 to create one.

# will go to ~/.ssh/authorized_key
ssh-copy-id -i ~/.ssh/id_rsa.pub ec2-user@<dns>.amazonaws.com

Add alias #

To make things easier

#!/bin/bash
alias ec2myapi='ec2-user@<dns>.amazonaws.com'

Add files to server #

#!/bin/bash

scp <some_file> ec2-user@<dns>.amazonaws.com:/home/ec2-user
...
...
...

Build Docker file #

sudo docker build -t my-api .
sudo docker run --publish 80:5000 my-api

Start your app and curl! #

curl "<dns>.amazonaws.com"