Skip to main content

FastAPI AWS Deployment

Amazon Web Services (AWS) offers a robust ecosystem for deploying your FastAPI applications. In this guide, you'll learn multiple approaches to deploy FastAPI on AWS, from simple to sophisticated solutions.

Introduction

Deploying a FastAPI application to a production environment involves more than just running your code on a server. You need to consider scalability, availability, security, and management capabilities. AWS provides several services that make deploying FastAPI applications straightforward while addressing these production concerns.

By the end of this guide, you'll understand various AWS deployment options and be able to choose the right one for your FastAPI application.

Prerequisites

Before proceeding, make sure you have:

  • A working FastAPI application
  • Basic understanding of FastAPI concepts
  • An AWS account
  • AWS CLI configured on your local machine
  • Basic knowledge of Docker (for container-based deployments)

Option 1: Deploy on EC2 (Virtual Server)

Amazon EC2 (Elastic Compute Cloud) is one of the most straightforward ways to deploy a FastAPI application on AWS.

Step 1: Create an EC2 Instance

  1. Log in to the AWS Management Console
  2. Navigate to EC2 Service
  3. Click "Launch Instance"
  4. Select Ubuntu Server 22.04 LTS (or your preferred Linux distribution)
  5. Choose an instance type (t2.micro is eligible for free tier)
  6. Configure security groups to allow HTTP (80), HTTPS (443), and SSH (22) traffic
  7. Create or select a key pair for SSH access
  8. Launch the instance

Step 2: Connect to Your Instance

bash
ssh -i /path/to/your-key.pem ubuntu@your-instance-public-dns

Step 3: Set Up the Environment

bash
# Update package lists
sudo apt update
sudo apt upgrade -y

# Install Python and pip
sudo apt install -y python3 python3-pip python3-venv

# Create a directory for your application
mkdir ~/fastapi-app
cd ~/fastapi-app

# Create and activate a virtual environment
python3 -m venv venv
source venv/bin/activate

# Install dependencies
pip install fastapi uvicorn gunicorn

Step 4: Deploy Your Application

Upload your FastAPI application code to the EC2 instance using SCP or Git:

Using SCP:

bash
scp -i /path/to/your-key.pem -r /path/to/your/local/app/* ubuntu@your-instance-public-dns:~/fastapi-app/

Using Git:

bash
# On EC2 instance
git clone https://github.com/yourusername/your-fastapi-repo.git
cd your-fastapi-repo
pip install -r requirements.txt

Step 5: Run with Gunicorn

Create a service file to manage your FastAPI application:

bash
sudo nano /etc/systemd/system/fastapi.service

Add the following content:

ini
[Unit]
Description=FastAPI application
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/fastapi-app
ExecStart=/home/ubuntu/fastapi-app/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8000
Restart=always

[Install]
WantedBy=multi-user.target

Start the service:

bash
sudo systemctl start fastapi
sudo systemctl enable fastapi

Step 6: Set Up Nginx as a Reverse Proxy

bash
sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/fastapi

Add the following configuration:

nginx
server {
listen 80;
server_name your_domain.com;

location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Enable the site and restart Nginx:

bash
sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo systemctl restart nginx

Your FastAPI application should now be accessible through your EC2 instance's public IP or domain!

Option 2: Deploy with AWS Elastic Beanstalk

AWS Elastic Beanstalk is a platform-as-a-service (PaaS) that streamlines deployment and management.

Step 1: Prepare Your FastAPI Project

Make sure your FastAPI project has the following structure:

my-fastapi-app/
├── application.py # Main application file
├── requirements.txt
└── .ebextensions/
└── 01_fastapi.config

Your application.py should have:

python
import uvicorn
from fastapi import FastAPI

app = FastAPI()

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

# This is needed for Elastic Beanstalk
application = app

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

Create a requirements.txt:

fastapi==0.103.1
uvicorn==0.23.2

Create .ebextensions/01_fastapi.config:

yaml
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: application:application
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: static

Step 2: Install EB CLI and Deploy

bash
# Install the EB CLI
pip install awsebcli

# Initialize EB application
cd my-fastapi-app
eb init -p python-3.8 fastapi-application

# Create an environment and deploy
eb create fastapi-env

# Once deployed, you can open the app
eb open

Step 3: Monitor and Update

After deployment, you can use these commands to manage your application:

bash
# View application status
eb status

# View logs
eb logs

# Update your application after changes
eb deploy

# Terminate the environment when no longer needed
eb terminate fastapi-env

Option 3: Containerize with AWS ECS (Elastic Container Service)

For more complex applications, containerization with Docker and AWS ECS provides better scalability and resource management.

Step 1: Create a Dockerfile

Create a Dockerfile in your project root:

dockerfile
FROM python:3.9-slim

WORKDIR /app

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

COPY . .

EXPOSE 8000

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

Step 2: Build and Push to Amazon ECR

bash
# Install AWS CLI and Docker if not already installed
# Log in to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com

# Create ECR repository
aws ecr create-repository --repository-name fastapi-app --region us-east-1

# Build and tag your Docker image
docker build -t fastapi-app .
docker tag fastapi-app:latest YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/fastapi-app:latest

# Push to ECR
docker push YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/fastapi-app:latest

Step 3: Create an ECS Cluster and Task Definition

  1. Open the ECS console
  2. Create a new cluster
  3. Create a task definition:
    • Use the container image from ECR
    • Map port 8000
    • Configure CPU and memory requirements
  4. Create an ECS service based on your task definition
  5. Configure a load balancer to route traffic to your containers

Option 4: Serverless with AWS Lambda

For serverless FastAPI deployment, you can use AWS Lambda with API Gateway.

Step 1: Prepare Your FastAPI Application for Lambda

Install required dependencies:

bash
pip install fastapi mangum

Update your main.py to work with Lambda:

python
from fastapi import FastAPI
from mangum import Mangum

app = FastAPI()

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

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}

# Handler for AWS Lambda
handler = Mangum(app)

Step 2: Package for Lambda Deployment

Create a requirements.txt:

fastapi==0.103.1
mangum==0.17.0

Create a deployment package:

bash
mkdir build
pip install -t build -r requirements.txt
cp main.py build/
cd build
zip -r ../lambda_function.zip .
cd ..

Step 3: Create Lambda Function and API Gateway

  1. Create a Lambda function:

    • Runtime: Python 3.9
    • Handler: main.handler
    • Upload your ZIP package
  2. Create an API Gateway:

    • REST API
    • Create a proxy resource with ANY method
    • Deploy the API to a stage
  3. Test your API using the provided endpoint URL

Advanced Configuration

Setting Up Custom Domain Names

To use custom domains with your FastAPI deployment, you can:

  1. Register a domain with Route 53 or another registrar
  2. Create an SSL certificate with AWS Certificate Manager
  3. Configure your load balancer or API Gateway with the custom domain
  4. Set up DNS records to point to your AWS resources

Implementing CI/CD for FastAPI on AWS

You can use AWS CodePipeline with CodeBuild to automate deployments:

  1. Create a repository in AWS CodeCommit or connect to GitHub
  2. Set up a CodeBuild project with a buildspec.yml file
  3. Create a CodePipeline to automatically deploy when code changes

Example buildspec.yml for a containerized FastAPI app:

yaml
version: 0.2

phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
build:
commands:
- echo Building the Docker image...
- docker build -t $ECR_REPOSITORY_URI:latest .
- docker tag $ECR_REPOSITORY_URI:latest $ECR_REPOSITORY_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION
post_build:
commands:
- echo Pushing the Docker image...
- docker push $ECR_REPOSITORY_URI:latest
- docker push $ECR_REPOSITORY_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION
- echo Writing image definitions file...
- aws ecs update-service --cluster $ECS_CLUSTER --service $ECS_SERVICE --force-new-deployment

Best Practices for FastAPI AWS Deployment

  1. Security:

    • Use AWS Secrets Manager for sensitive information
    • Implement AWS IAM roles and policies properly
    • Keep your dependencies updated
    • Enable HTTPS with valid certificates
  2. Performance:

    • Set appropriate instance sizes for your workload
    • Enable auto-scaling to handle traffic spikes
    • Use caching strategies where appropriate
  3. Monitoring:

    • Set up CloudWatch alarms for performance metrics
    • Configure logging to capture application errors
    • Use X-Ray for tracing requests through your application
  4. Cost Management:

    • Schedule scaling down during low-traffic periods
    • Use Spot Instances for non-critical workloads
    • Regularly review and optimize AWS resource usage

Real-World Example: FastAPI REST API with Database

This example shows how to deploy a FastAPI application with a PostgreSQL database on AWS.

Step 1: Create an RDS PostgreSQL Instance

  1. Open the RDS console
  2. Create a new PostgreSQL database
  3. Make sure it's in the same VPC as your deployment
  4. Configure security groups to allow access from your application

Step 2: Update Your FastAPI Application

python
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session
import os

# Database setup
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://user:password@localhost/dbname")
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
description = Column(String)

# Create tables
Base.metadata.create_all(bind=engine)

app = FastAPI()

# Dependency to get DB session
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

@app.post("/items/", response_model=dict)
def create_item(name: str, description: str, db: Session = Depends(get_db)):
item = Item(name=name, description=description)
db.add(item)
db.commit()
db.refresh(item)
return {"id": item.id, "name": item.name, "description": item.description}

@app.get("/items/{item_id}")
def read_item(item_id: int, db: Session = Depends(get_db)):
item = db.query(Item).filter(Item.id == item_id).first()
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
return {"id": item.id, "name": item.name, "description": item.description}

Step 3: Deploy with Environment Variables

When deploying to AWS, set the DATABASE_URL environment variable to your RDS instance connection string in your deployment configuration.

Summary

In this comprehensive guide, we've explored multiple ways to deploy FastAPI applications on AWS:

  1. EC2 deployment - Traditional virtual server approach using Nginx and Gunicorn
  2. Elastic Beanstalk - PaaS solution that simplifies management and deployment
  3. ECS containers - Docker-based deployment for better scalability and isolation
  4. Serverless with Lambda - Event-driven architecture with minimal maintenance

Each approach has its strengths and ideal use cases:

  • Use EC2 for maximum control and customization
  • Use Elastic Beanstalk for simplicity and ease of management
  • Use ECS for complex, microservice-based applications
  • Use Lambda for cost-efficient, event-driven applications

Additional Resources

Exercises

  1. Deploy a simple FastAPI "Hello World" application to EC2
  2. Modify the application to connect to an RDS database instance
  3. Implement auto-scaling for your FastAPI application on Elastic Beanstalk
  4. Create a CI/CD pipeline for your FastAPI application using AWS CodePipeline
  5. Deploy a serverless FastAPI application with custom domain name

By completing these exercises, you'll gain hands-on experience with different AWS deployment options for FastAPI applications.

Happy deploying!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)