Skip to main content

Deploying FastAPI to AWS Fargate: A Comprehensive Guide

Project Structure

fastapi-app/

├── app/
│ ├── main.py
│ └── __init__.py

├── requirements.txt
├── Dockerfile
└── .dockerignore

1. Prepare the FastAPI Application

main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
return {"message": "Hello, FastAPI on AWS Fargate!"}

requirements.txt

fastapi
uvicorn[standard]

2. Create Dockerfile

# Use lightweight Python base image
FROM python:3.10-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY ./app ./app

# Run the application
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

3. Prepare AWS Resources

Install Prerequisites

  1. AWS CLI
  2. Docker
  3. AWS CDK
  4. Node.js and npm
# Install CDK CLI
npm install -g aws-cdk

# Initialize CDK Python project
mkdir fastapi-fargate-cdk
cd fastapi-fargate-cdk
cdk init app --language python

# Install required CDK modules
pip install aws-cdk-lib constructs boto3

4. Build and Push Docker Image to Amazon ECR

# Create ECR Repository
aws ecr create-repository --repository-name fastapi-app

# Login to ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com

# Build Docker Image
docker build -t fastapi-app .

# Tag and Push Image
docker tag fastapi-app:latest <account_id>.dkr.ecr.<region>.amazonaws.com/fastapi-app:latest
docker push <account_id>.dkr.ecr.<region>.amazonaws.com/fastapi-app:latest

5. Create CDK Stack for Deployment

app.py

#!/usr/bin/env python3
import aws_cdk as cdk
from fastapi_fargate_cdk.fastapi_fargate_stack import FastapiFargateStack

app = cdk.App()
FastapiFargateStack(app, "FastapiFargateStack")
app.synth()

fastapi_fargate_stack.py

from aws_cdk import (
Stack,
aws_ec2 as ec2,
aws_ecs as ecs,
aws_ecs_patterns as ecs_patterns,
aws_iam as iam,
)
from constructs import Construct

class FastapiFargateStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)

# Create VPC
vpc = ec2.Vpc(self, "FastapiVpc", max_azs=2)

# Create ECS Cluster
cluster = ecs.Cluster(self, "FastapiCluster", vpc=vpc)

# Task Role
task_role = iam.Role(
self,
"TaskRole",
assumed_by=iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
)

# Fargate Task Definition
task_definition = ecs.FargateTaskDefinition(
self,
"FastapiTaskDef",
memory_limit_mib=512,
cpu=256,
task_role=task_role,
)

# Add Container
container = task_definition.add_container(
"FastapiContainer",
image=ecs.ContainerImage.from_registry(
"<account_id>.dkr.ecr.<region>.amazonaws.com/fastapi-app:latest"
),
logging=ecs.LogDrivers.aws_logs(stream_prefix="FastapiLogs"),
)

# Port Mapping
container.add_port_mappings(
ecs.PortMapping(container_port=80, host_port=80)
)

# Create Fargate Service with Load Balancer
ecs_patterns.ApplicationLoadBalancedFargateService(
self,
"FastapiFargateService",
cluster=cluster,
task_definition=task_definition,
public_load_balancer=True,
)

6. Deploy the Stack

# Synthesize CDK template
cdk synth

# Deploy the stack
cdk deploy

Optional Enhancements

HTTPS Support

from aws_cdk import aws_certificatemanager as cert_manager

ecs_patterns.ApplicationLoadBalancedFargateService(
# ... other parameters ...
certificate=cert_manager.Certificate.from_certificate_arn(
self, "Cert", "<certificate_arn>"
),
protocol=ecs.ApplicationProtocol.HTTPS,
)

Considerations

  • Set up CI/CD with AWS CodePipeline or GitHub Actions
  • Configure auto-scaling based on traffic
  • Manage log groups efficiently
  • Implement security best practices

Troubleshooting

  • Verify Docker image builds correctly
  • Check ECR repository permissions
  • Ensure VPC and security group configurations
  • Validate CDK stack parameters