How to Deploy a Python FastAPI App to AWS: Complete Beginner Guide

FastAPI is one of the fastest-growing Python web frameworks, known for its speed, automatic API documentation, and modern async support. But building your app locally is only half the battle — you need to deploy it.

This guide walks you through deploying a FastAPI application to AWS EC2 from scratch, including server setup, Nginx reverse proxy, process management with systemd, and SSL certificates.

What You Will Learn

  • Launch and configure an AWS EC2 instance
  • Install Python and project dependencies
  • Run FastAPI with Uvicorn in production
  • Set up Nginx as a reverse proxy
  • Create a systemd service for auto-restart
  • Add SSL/HTTPS with Let's Encrypt

Prerequisites

  • An AWS account (free tier eligible)
  • A FastAPI application ready to deploy
  • A domain name (optional but recommended for SSL)
  • Basic familiarity with the Linux command line
  • An SSH client (Terminal on Mac/Linux, PuTTY on Windows)

Step 1: Launch an EC2 Instance

  1. Log in to the AWS EC2 Console
  2. Click Launch Instance
  3. Choose Ubuntu 22.04 LTS (or newer) as the AMI
  4. Select t2.micro (free tier eligible) or t3.small for production
  5. Create or select a key pair for SSH access — download the .pem file
  6. Configure Security Group to allow:
    • SSH (port 22) from your IP
    • HTTP (port 80) from anywhere
    • HTTPS (port 443) from anywhere
  7. Launch the instance

Step 2: Connect to Your Instance

chmod 400 your-key.pem
ssh -i your-key.pem ubuntu@your-ec2-public-ip

Replace your-ec2-public-ip with the public IP from your EC2 dashboard.

Step 3: Install Python and Dependencies

# Update system packages
sudo apt update && sudo apt upgrade -y

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

# Verify installation
python3 --version
pip3 --version

Step 4: Upload and Set Up Your Project

Option A: Clone from Git (recommended)

cd /home/ubuntu
git clone https://github.com/yourusername/your-fastapi-app.git
cd your-fastapi-app

Option B: Upload with SCP

# From your local machine:
scp -i your-key.pem -r ./your-fastapi-app ubuntu@your-ec2-public-ip:/home/ubuntu/

Create a Virtual Environment

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Step 5: Test Your App

Make sure your app runs before configuring the server:

uvicorn main:app --host 0.0.0.0 --port 8000

Visit http://your-ec2-public-ip:8000/docs in your browser. You should see the FastAPI Swagger documentation. Press Ctrl+C to stop.

Note: You may need to temporarily add port 8000 to your EC2 security group for this test. Remove it after you set up Nginx.

Step 6: Create a systemd Service

systemd will run your app in the background and automatically restart it if it crashes or the server reboots.

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

Paste the following:

[Unit]
Description=FastAPI Application
After=network.target

[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/your-fastapi-app
Environment="PATH=/home/ubuntu/your-fastapi-app/venv/bin"
ExecStart=/home/ubuntu/your-fastapi-app/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 --workers 4
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Enable and Start the Service

sudo systemctl daemon-reload
sudo systemctl enable fastapi
sudo systemctl start fastapi

# Check status
sudo systemctl status fastapi

You should see active (running) in the output.

Step 7: Install and Configure Nginx

Nginx acts as a reverse proxy — it receives HTTP requests on port 80 and forwards them to your FastAPI app on port 8000.

sudo apt install -y nginx

Create Nginx Configuration

sudo nano /etc/nginx/sites-available/fastapi

Paste:

server {
    listen 80;
    server_name your-domain.com;  # or your EC2 public IP

    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;
    }
}

Enable the Configuration

# Create symbolic link
sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/

# Remove default config
sudo rm /etc/nginx/sites-enabled/default

# Test configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx

Now visit http://your-domain.com (or your EC2 IP) — your FastAPI app should be live on port 80.

Step 8: Add SSL with Let's Encrypt

If you have a domain name pointed to your EC2 instance, add free SSL:

# Install Certbot
sudo apt install -y certbot python3-certbot-nginx

# Get and install certificate
sudo certbot --nginx -d your-domain.com

# Follow the prompts — Certbot will automatically configure Nginx for HTTPS

Certbot automatically sets up auto-renewal. Your site will now be accessible at https://your-domain.com.

Step 9: Environment Variables

For production secrets (database URLs, API keys), create an environment file:

sudo nano /home/ubuntu/your-fastapi-app/.env

Add your variables:

DATABASE_URL=mongodb+srv://user:pass@cluster.mongodb.net/db
SECRET_KEY=your-secret-key
ENVIRONMENT=production

Update your systemd service to load it:

# Add this line under [Service] in /etc/systemd/system/fastapi.service
EnvironmentFile=/home/ubuntu/your-fastapi-app/.env

Then reload:

sudo systemctl daemon-reload
sudo systemctl restart fastapi

Useful Commands

# View app logs
sudo journalctl -u fastapi -f

# Restart app after code changes
sudo systemctl restart fastapi

# Check Nginx logs
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

# Update code from Git
cd /home/ubuntu/your-fastapi-app
git pull
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart fastapi

Production Best Practices

  • Use multiple Uvicorn workers — the --workers 4 flag in the systemd service runs 4 worker processes for better concurrency
  • Set up a firewall — use ufw to only allow ports 22, 80, and 443
  • Enable automatic security updatessudo apt install unattended-upgrades
  • Monitor your app — use CloudWatch, Datadog, or a simple health check endpoint
  • Back up your database — MongoDB Atlas handles this automatically
  • Use a non-root user — the ubuntu user is fine, never run your app as root
  • Rotate secrets — change API keys and database passwords periodically

Alternative: Deploy with Docker

If you prefer containers, you can also deploy with Docker:

# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
# Build and run
docker build -t fastapi-app .
docker run -d -p 8000:8000 --env-file .env fastapi-app

Then use the same Nginx reverse proxy setup from Step 7.

Conclusion

Deploying FastAPI to AWS is straightforward once you understand the pieces: EC2 for the server, Uvicorn for running your Python app, Nginx for routing traffic, systemd for reliability, and Let's Encrypt for free SSL.

This setup handles most small-to-medium production workloads. When you need to scale further, consider AWS ECS with Docker containers, or a load balancer in front of multiple EC2 instances.

Last updated: Sun Mar 08 2026