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
- Log in to the AWS EC2 Console
- Click Launch Instance
- Choose Ubuntu 22.04 LTS (or newer) as the AMI
- Select t2.micro (free tier eligible) or t3.small for production
- Create or select a key pair for SSH access — download the .pem file
- Configure Security Group to allow:
- SSH (port 22) from your IP
- HTTP (port 80) from anywhere
- HTTPS (port 443) from anywhere
- 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 4flag in the systemd service runs 4 worker processes for better concurrency - Set up a firewall — use
ufwto only allow ports 22, 80, and 443 - Enable automatic security updates —
sudo 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.