APIs have become vital to modern applications, enabling seamless integration between services. FastAPI, a modern web framework for Python, is particularly popular for building fast APIs due to its asynchronous capabilities and performance. It is powered by Uvicorn. This post walks through deploying a FastAPI application with a custom domain, secured with SSL using Let’s Encrypt, hosted on AWS EC2, and served via Nginx.

Introduction to Deploying APIs with FastAPI and Uvicorn

FastAPI, paired with Uvicorn (an ASGI web server), provides a robust, high-performance framework for building APIs. Deploying this combination on an AWS EC2 instance ensures that your APIs can handle real-world traffic and provide secure, efficient communication.

Setting Up Local Development Environment

Before moving to deployment, it’s crucial to have your local development environment ready. Here’s a simple setup:

  1. Install FastAPI and Uvicorn:
    pip install fastapi uvicorn
  2. Create a Simple FastAPI App:
    from fastapi import FastAPI

app = FastAPI()

@app.get(“/”)

async def root():

    return {“message”: “Hello World”}

  1. Run the FastAPI App Locally:
    uvicorn main:app –reload

This allows you to develop and test locally before deploying to the cloud.

Preparing AWS EC2 Instance for Hosting

Now that you have a basic FastAPI app running locally, it’s time to move it to the cloud.

  1. Launch an EC2 Instance:
    • Go to the AWS Management Console and create a new EC2 instance. Use an Amazon Linux 2 or Ubuntu image for easy setup.
    • Choose instance size based on expected traffic (t2.micro for small apps is sufficient).
    • Configure your security group to allow HTTP (port 80), HTTPS (port 443), and SSH (port 22).
  1. SSH into the EC2 Instance:
    ssh -i “your-key.pem” ec2-user@your-instance-public-dns

Assigning Elastic IP and Installing Dependencies

  1. Assign an Elastic IP to Your Instance:
    • In the AWS EC2 dashboard, allocate a new Elastic IP.
    • Associate the Elastic IP with your EC2 instance to ensure a static IP address.
  1. Install Dependencies:
    Install required software like Python, Uvicorn, Git, Nginx, and Certbot.

sudo yum update

sudo yum install python3 git nginx -y

sudo pip3 install fastapi uvicorn

Configuring SSL Certificates with Let’s Encrypt

To ensure secure communication over HTTPS, we will use Let’s Encrypt to configure SSL certificates.

  1. Install Certbot:
    sudo yum install certbot python3-certbot-nginx
  2. Obtain SSL Certificates:
    Before running Certbot, ensure your domain is pointed to your Elastic IP (more on domain mapping below). Once that’s done:
    sudo certbot –nginx -d yourdomain.com -d www.yourdomain.com

This will automatically configure Nginx to use SSL certificates from Let’s Encrypt.

Setting Up Nginx as a Reverse Proxy

To serve the FastAPI application with Nginx, you need to configure Nginx as a reverse proxy.

  1. Configure Nginx for FastAPI:
    Open the Nginx configuration file for editing:
    sudo nano /etc/nginx/nginx.conf

Add the following server block to proxy requests to Uvicorn:
server {

    listen 80;

    server_name yourdomain.com www.yourdomain.com;

    location / {

        proxy_pass http://127.0.0.1:8000;

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

    }

}

  1. Start Uvicorn in the Background:
    Use a tool like systemd to manage Uvicorn as a service.
    sudo nano /etc/systemd/system/fastapi.service

Add the following configuration:
[Unit]

Description=FastAPI Uvicorn Service

[Service]

ExecStart=/usr/local/bin/uvicorn main:app –host 0.0.0.0 –port 8000

WorkingDirectory=/home/ec2-user/your-fastapi-app

Restart=always

User=ec2-user

[Install]

WantedBy=multi-user.target

Enable and start the service:
sudo systemctl enable fastapi

sudo systemctl start fastapi

  1. Restart Nginx to Apply Changes:
    sudo systemctl restart nginx

Mapping Domain to AWS EC2 Instance

  1. Register a Domain Name:
    If you don’t have a domain yet, register one through services like AWS Route 53, Namecheap, or GoDaddy.
  2. Point Domain to Elastic IP:
    In your domain registrar’s DNS settings, create an A record pointing to your EC2 instance’s Elastic IP address.

    • Type: A
    • Name: @ (or www)
    • Value: Your Elastic IP

This step is crucial for both setting up SSL with Let’s Encrypt and accessing your API via a custom domain.

Verifying Deployment and Accessing APIs

With everything configured, you can now verify the deployment by accessing your domain. Visit https://yourdomain.com to check if the FastAPI app is live and secured via SSL.

To ensure everything is working correctly:

  1. Check the SSL Certificate: Confirm that the site is accessible via HTTPS and that SSL is configured correctly.
  2. Test the API: Navigate to https://yourdomain.com/docs to access the interactive FastAPI documentation.

References

Deploying a Flask application to Elastic Beanstalk

Using the Elastic Beanstalk Python platform