Flask API on AWS EC2

Deploying a Flask API to AWS EC2 Using Docker and GitHub Actions for CI/CD Pipeline

A complete walkthrough on building, containerizing, automating, and deploying a Flask REST API to AWS EC2 using Docker and GitHub Actions.


๐Ÿงญ Introduction

In this project, I created a simple Flask REST API, packaged it into a Docker container, and deployed it to an AWS EC2 instance via a CI/CD pipeline using GitHub Actions. This tutorial demonstrates how to:

  • Build a lightweight API using Flask

  • Containerize the application with Docker

  • Set up a GitHub Actions workflow for continuous integration and deployment

  • Deploy and manage the container on an EC2 instance automatically

๐Ÿ“‚ GitHub Repo: Flash_API-Docker-Project


โš™๏ธ Phase 1: Building the Flask REST API

Weโ€™ll start with a minimal Flask app that provides basic CRUD functionality.

app.py:

from flask import Flask, jsonify, request

app = Flask(__name__)
data_store = []

@app.route("/", methods=["GET"])
def home():
    return jsonify({"message": "Welcome to the Flask REST API!"})

@app.route("/items", methods=["GET"])
def get_items():
    return jsonify(data_store)

@app.route("/items", methods=["POST"])
def add_item():
    item = request.json
    data_store.append(item)
    return jsonify({"status": "Item added", "item": item}), 201

@app.route("/items/<int:index>", methods=["DELETE"])
def delete_item(index):
    try:
        removed = data_store.pop(index)
        return jsonify({"status": "Item removed", "item": removed})
    except IndexError:
        return jsonify({"error": "Item not found"}), 404

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Screenshot: Sample response from the root endpoint


๐Ÿณ Phase 2: Dockerizing the Flask App

Create a Dockerfile to package the app.

Dockerfile:

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

requirements.txt:

Flask==2.3.2

To build and test locally:

docker build -t flask-api .
docker run -d -p 5000:5000 flask-api

Screenshot: Docker container running locally


๐Ÿš€ Phase 3: Setting Up GitHub Actions for CI/CD

Create a workflow under .github/workflows/deploy.yml.

Workflow Highlights:

  • Build Docker image

  • Push to Docker Hub

  • SSH into EC2 instance and deploy container

deploy.yml:

name: CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build-deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Login to DockerHub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build and push Docker image
      uses: docker/build-push-action@v4
      with:
        push: true
        tags: ${{ secrets.DOCKER_USERNAME }}/flask-api:latest

    - name: Deploy to EC2
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.EC2_HOST }}
        username: ${{ secrets.EC2_USER }}
        key: ${{ secrets.EC2_SSH_KEY }}
        script: |
          docker pull ${{ secrets.DOCKER_USERNAME }}/flask-api:latest
          docker stop flask-api || true
          docker rm flask-api || true
          docker run -d --name flask-api -p 80:5000 ${{ secrets.DOCKER_USERNAME }}/flask-api:latest

Screenshot: GitHub Actions pipeline stages


โ˜๏ธ Phase 4: EC2 Deployment Output

Once the container is deployed, visiting the EC2 Public IP should show the root response.

Screenshot: API output from deployed EC2 instance


๐Ÿ” GitHub Secrets to Configure

  • DOCKER_USERNAME

  • DOCKER_PASSWORD

  • EC2_HOST

  • EC2_USER

  • EC2_SSH_KEY

These are accessed securely in the GitHub Actions workflow.


๐Ÿ“Œ Summary

โœ… Built a simple Flask REST API
โœ… Containerized the app using Docker
โœ… Automated deployment using GitHub Actions
โœ… Deployed and verified the app on AWS EC2

๐Ÿ“‚ Repo: Flash_API-Docker-Project


๐Ÿ™Œ Final Thoughts

This project reinforced key DevOps principles including containerization, automation, and cloud deployment. It's a great starter for real-world CI/CD experience and can be extended with monitoring, HTTPS, and more advanced pipelines.

Feel free to fork the repo, try the steps, and drop your feedback or improvements!

0
Subscribe to my newsletter

Read articles from pradeep mahadevaiah directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

pradeep mahadevaiah
pradeep mahadevaiah