How to Deploy a REST API on AWS EC2 with Python and Docker
Table of Contents
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"