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
- AWS CLI
- Docker
- AWS CDK
- 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