What Happens When You Take FastAPI, Docker & CI/CD on a Wild Ride?

**Crafting Rock-Solid APIs: FastAPI + Docker + CI/CD Magic**

What Happens When You Take FastAPI, Docker & CI/CD on a Wild Ride?

Building scalable APIs doesn’t have to be a headache. If you’re into modern web development, you need to know about combining FastAPI with Docker and CI/CD pipelines. This cocktail lets you develop superb APIs that won’t buckle under pressure and are easy to maintain.

Let’s dive into it.

Getting Cozy with FastAPI

FastAPI is like Python’s cool cousin who knows all the latest trends. It’s a sleek, high-performance web framework designed for creating APIs with Python 3.7+—and it’s a breeze to use. Check out this super basic FastAPI app:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

Yep, that’s all it takes to set up a FastAPI app and create a single endpoint at /. Fast, right?

Dockerizing Your FastAPI App

Docker is the unsung hero that ensures your app works the same everywhere—from your laptop to the cloud. It’s about portability and consistency. Here’s how you Dockerize that FastAPI app:

First, you need a Dockerfile. Think of it as a recipe that defines how to package your app:

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

Next, you build the Docker image:

docker build -t fastapi-docker .

And run the Docker container:

docker run -d -p 8000:8000 --name my-fastapi-container fastapi-docker

Easy-peasy. Your FastAPI app is now bundled up with all its dependencies, running smoothly like butter across various environments.

Setting Up CI/CD Pipelines

The magic of modern web development is found in CI/CD pipelines, which automate everything from testing to deployment. Here’s a simplified way of setting up a CI/CD pipeline using GitHub Actions:

Create a GitHub Actions workflow file:

name: FastAPI CI/CD

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Python 3.9
        uses: actions/setup-python@v2
        with:
          python-version: '3.9'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run tests
        run: |
          pytest

      - name: Build Docker image
        run: |
          docker build -t fastapi-docker .

      - name: Push to AWS ECR
        uses: aws-actions/amazon-ecr-login@v1
        id: login
        with:
          role-to-assume: arn:aws:iam::123456789012:role/ECRPushRole
          region: us-east-1

      - name: Push image to ECR
        run: |
          aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
          docker tag fastapi-docker:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/fastapi-docker:latest
          docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/fastapi-docker:latest

      - name: Deploy to EC2
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PRIVATE_KEY }}
          script: |
            docker pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/fastapi-docker:latest
            docker stop my-fastapi-container || true
            docker rm my-fastapi-container || true
            docker run -d -p 8000:8000 --name my-fastapi-container 123456789012.dkr.ecr.us-east-1.amazonaws.com/fastapi-docker:latest

This setup is like having a personal butler for your code. It checks out your code, sets up the Python environment, installs dependencies, runs tests, builds a Docker image, and even pushes it to AWS ECR before deploying it to an EC2 instance. How awesome is that?

Running Tests in CI/CD Pipelines

Testing is the unsung hero of a smooth CI/CD pipeline. You need to make sure your code works before it hits production. Here’s how you can run tests in your pipeline:

First, write your test cases. For FastAPI, it’s super simple:

from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_read_root():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"Hello": "World"}

Integrate this into your GitHub Actions workflow:

- name: Run tests
  run: |
    pytest

Voila! Every time you push to your main branch, your tests will run to catch any nasty bugs early on.

Deploying to AWS EKS

Now, for the big leagues. If you’re looking for top-tier scalability and resilience, Amazon’s Elastic Kubernetes Service (EKS) is where you want to go. Here’s the lowdown:

First, set up an EKS cluster:

eksctl create cluster --name=minimal-cluster --region=us-east-1 --nodegroup-name=minimal-nodes --node-type=t3.micro --nodes=1 --nodes-min=1 --nodes-max=2 --node-volume-size=10 --managed

Next, create a Kubernetes deployment YAML file for your FastAPI app:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: fastapi
  template:
    metadata:
      labels:
        app: fastapi
    spec:
      containers:
      - name: fastapi
        image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/fastapi-docker:latest
        ports:
        - containerPort: 8000

Then apply this deployment:

kubectl apply -f deployment.yaml

Just like that, your FastAPI application is running on Kubernetes, ready to scale up and handle traffic spikes like a champ.

Wrapping It Up

Pairing FastAPI with Docker and CI/CD pipelines is your ticket to building rock-solid APIs that don’t break under pressure. Docker makes sure your app is consistent, CI/CD workflows automate testing and deployment, and tools like Kubernetes (through AWS EKS) ensure you can handle anything the internet throws your way.

This approach isn’t just about putting your app out there; it’s about making sure it stays robust, scales effortlessly, and gives your end-users a seamless experience. So go ahead, and dive into this powerful stack. Your future self—and your users—will thank you.