Deploying Python Apps to AWS: A Complete Beginner's Guide
A beginner's guide to deploying Python apps to AWS in 2025: EC2, Lambda, Elastic Beanstalk, and free alternatives — step-by-step with real commands.
Get more content like this on Telegram!
Daily AI tips, notes & resources — free
Deploying Python Apps to AWS: A Complete Beginner's Guide
Getting a Python app running on your laptop is step one. Getting it running reliably in the cloud, accessible to the world, is step two — and it's where many beginners get stuck.
This guide demystifies AWS deployment for Python apps. I'll cover the main options (EC2, Lambda, Elastic Beanstalk), give you working commands, and tell you honestly when simpler alternatives are better.
Before AWS: Should You Use AWS?
AWS is powerful, but it's not always the right choice for beginners. Let me be direct:
Consider Railway, Render, or Fly.io first if:
- You're deploying a hobby project or portfolio piece
- You want to deploy in under 10 minutes without learning AWS
- You don't specifically need AWS for a job or project requirement
Use AWS if:
- Your team or employer uses AWS
- You need specific AWS services (RDS, S3, SQS)
- You're learning AWS for career reasons
- Your app needs to scale significantly
For a portfolio project, Railway or Render gives you a live URL in 5 minutes. AWS gives you the same result in 30–60 minutes with more configuration. Know your goal before choosing.
Option 1: AWS Lambda (Serverless Python)
Lambda runs Python functions in response to events — HTTP requests, scheduled triggers, file uploads. You don't manage any servers.
Deploying a Simple FastAPI App to Lambda
# main.py
from fastapi import FastAPI
from mangum import Mangum
app = FastAPI()
@app.get("/")
def root():
return {"message": "Running on Lambda"}
@app.get("/hello/{name}")
def hello(name: str):
return {"message": f"Hello, {name}!"}
# Mangum wraps FastAPI for Lambda
handler = Mangum(app)
Deployment with AWS SAM
# Install AWS CLI and SAM CLI
pip install aws-sam-cli
Create template.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
PythonApi:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Handler: main.handler
Runtime: python3.11
MemorySize: 256
Timeout: 30
Events:
Api:
Type: HttpApi
Properties:
Path: /{proxy+}
Method: ANY
Create requirements.txt:
fastapi
mangum
Deploy:
sam build
sam deploy --guided
SAM will ask for a stack name, region, and confirmation. After deployment, you'll receive an API URL.
Limitations of Lambda:
- Cold starts (first request after ~5 minutes idle is slower — 500ms–2s)
- 15 minute maximum execution time
- Local file system is read-only (use S3 for file storage)
- 10GB maximum package size
Option 2: EC2 (Virtual Machine)
EC2 gives you a full virtual machine. More control, more setup, always running.
Step 1: Launch an EC2 Instance
- Sign into AWS Console → EC2 → Launch Instance
- Choose: Ubuntu Server 22.04 LTS (free tier eligible)
- Instance type: t2.micro (free tier)
- Key pair: Create new, download .pem file
- Security group: Allow SSH (port 22) and HTTP (port 80)
- Launch
Step 2: Connect to Your Instance
# Make key file secure
chmod 400 your-key.pem
# Connect
ssh -i your-key.pem ubuntu@your-ec2-public-ip
Step 3: Install Python and Dependencies
# Update system
sudo apt update && sudo apt upgrade -y
# Install Python and pip
sudo apt install python3 python3-pip python3-venv nginx -y
# Create app directory
mkdir ~/app && cd ~/app
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
Step 4: Deploy Your FastAPI App
# Upload your app (from local machine)
scp -i your-key.pem -r ./app ubuntu@your-ec2-ip:~/app/
# On the server: install dependencies
pip install fastapi uvicorn gunicorn
Step 5: Configure Gunicorn as a Service
Create /etc/systemd/system/fastapi.service:
[Unit]
Description=FastAPI application
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/app
Environment="PATH=/home/ubuntu/app/venv/bin"
ExecStart=/home/ubuntu/app/venv/bin/gunicorn main:app -w 2 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
[Install]
WantedBy=multi-user.target
sudo systemctl start fastapi
sudo systemctl enable fastapi
sudo systemctl status fastapi
Step 6: Configure Nginx as Reverse Proxy
sudo nano /etc/nginx/sites-available/fastapi
server {
listen 80;
server_name 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;
}
}
sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Your app is now accessible at http://your-ec2-public-ip.
Option 3: Elastic Beanstalk (Managed PaaS)
Elastic Beanstalk handles the EC2 setup, load balancing, and deployment for you. More expensive than raw EC2, but much simpler.
pip install awsebcli
In your project directory:
eb init -p python-3.11 my-python-app
eb create my-python-env
eb deploy
Elastic Beanstalk expects a application.py or application callable. For FastAPI:
# application.py
from fastapi import FastAPI
from mangum import Mangum
application = FastAPI()
@application.get("/")
def root():
return {"status": "ok"}
Option 4: Docker on ECS (Production-Grade)
For production apps, Docker + ECS Fargate is the modern standard.
Create a Dockerfile
FROM python:3.11-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"]
# Build and push to ECR
aws ecr create-repository --repository-name my-python-app
docker build -t my-python-app .
docker tag my-python-app:latest <account-id>.dkr.ecr.<region>.amazonaws.com/my-python-app:latest
docker push <account-id>.dkr.ecr.<region>.amazonaws.com/my-python-app:latest
Then create an ECS Fargate service from the ECR image in the AWS Console.
Environment Variables and Secrets
Never hardcode secrets in code. Use AWS Systems Manager Parameter Store or Secrets Manager:
import boto3
def get_secret(secret_name: str) -> str:
client = boto3.client("secretsmanager")
response = client.get_secret_value(SecretId=secret_name)
return response["SecretString"]
DATABASE_URL = get_secret("my-app/database-url")
For Lambda and EC2, environment variables are the simpler approach:
import os
DATABASE_URL = os.environ["DATABASE_URL"]
Simpler Alternatives for Beginners
If AWS feels overwhelming, these alternatives are production-ready and developer-friendly:
| Platform | Free Tier | Deploy Time | Best For |
|---|---|---|---|
| Railway | $5/month credit | 5 minutes | Hobby projects, startups |
| Render | 750h/month free | 5 minutes | Web services, static sites |
| Fly.io | Generous free | 10 minutes | Containers, global deployment |
| PythonAnywhere | Free tier | 5 minutes | Simple Python web apps |
For building the FastAPI apps you'll deploy, see our FastAPI tutorial. For OOP patterns that make deployed apps maintainable, our Python OOP guide covers the structure large applications need.
Frequently Asked Questions
Easiest way to deploy Python to AWS?
Elastic Beanstalk for web apps, Lambda for event-driven functions. For simplicity without AWS: Railway or Render.
How much does AWS cost for Python?
Free Tier covers most small apps for 12 months. After that, ~$8–10/month for a t3.micro.
Lambda vs EC2?
Lambda for infrequent/event-driven tasks. EC2 for always-on web servers and long-running processes.
Best Python framework for AWS?
FastAPI with Mangum for Lambda. FastAPI with Gunicorn for EC2/ECS.
Final Thoughts
AWS deployment isn't as scary as its reputation suggests, but it does require more setup than alternatives. The EC2 path gives you the most control and the most to learn; Lambda is elegant for the right use cases.
For learning projects and portfolios, Railway or Render give you the live URL with a fraction of the setup. When you're working professionally with teams that use AWS, you'll learn the specifics in context.
The most important deployment skill isn't knowing every AWS service — it's understanding the pattern: application → reverse proxy → server → domain. Whether that's on AWS, Railway, or your own hardware, the fundamentals are the same.
For the Python automation skills that complement server deployment (monitoring scripts, log processing, deployment automation), see our Python automation scripts guide.
Frequently Asked Questions
AiTechWorlds Team
✓ Verified WriterThe AiTechWorlds team is passionate about AI, technology, and education. We create high-quality, research-backed content to help you learn, grow, and succeed in the modern digital world.
Related Articles
The Python Libraries Every Developer Must Know in 2025
The essential Python libraries for 2025: from requests and pandas to FastAPI and LangChain — what each does, when to use it, and how to get started quickly.
Django vs Flask in 2025: Which Framework Should You Learn?
An honest Django vs Flask comparison for 2025 — which Python framework to learn first, when each excels, and why FastAPI has changed the equation.
FastAPI Tutorial: Building Your First REST API in 30 Minutes
A hands-on FastAPI tutorial for beginners: build a fully functional REST API in 30 minutes with CRUD endpoints, request validation, and automatic docs.
Jupyter Notebook Guide: The Data Scientist's Favorite Tool
A complete Jupyter Notebook guide for 2025: installation, essential shortcuts, best practices, and how data scientists use Jupyter for exploration, analysis, and sharing.