[2026] Python Web Deployment | Heroku, AWS, and Docker in Practice
이 글의 핵심
Deploy Python web apps: requirements.txt,.env, Gunicorn, Docker and Compose, Heroku, AWS EC2 with Nginx, systemd, and a production-minded checklist.
Introduction
“Development is done—time to deploy”
Deployment is the process of shipping your application to real users.
1. Deployment prep
requirements.txt
# Generate pinned dependencies
pip freeze > requirements.txt
Flask==2.3.0
gunicorn==20.1.0
python-dotenv==1.0.0
Environment variables (.env)
다음은 간단한 python 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# .env
SECRET_KEY=your-secret-key
DATABASE_URL=postgresql://user:pass@localhost/db
DEBUG=False
아래 코드는 python를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 코드를 직접 실행해보면서 동작을 확인해보세요.
# app.py
from dotenv import load_dotenv
import os
load_dotenv()
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config['DEBUG'] = os.getenv('DEBUG', 'False') == 'True'
2. Gunicorn
Running with Gunicorn
아래 코드는 bash를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# Install
pip install gunicorn
# Run
gunicorn app:app
# Workers and bind address
gunicorn -w 4 -b 0.0.0.0:8000 app:app
gunicorn.conf.py
아래 코드는 python를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
bind = "0.0.0.0:8000"
workers = 4
worker_class = "sync"
timeout = 30
keepalive = 2
3. Docker deployment
Dockerfile
아래 코드는 dockerfile를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "app:app"]
docker-compose.yml
다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
# Start stack
docker-compose up -d
4. Heroku deployment
Procfile
web: gunicorn app:app
runtime.txt
python-3.11.0
Deploy commands
아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# After installing Heroku CLI
heroku login
heroku create myapp
# Set config
heroku config:set SECRET_KEY=your-secret-key
# Deploy
git push heroku main
# Logs
heroku logs --tail
5. AWS deployment (EC2)
EC2 setup
다음은 bash를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# SSH into server
ssh -i key.pem ubuntu@ec2-instance
# Install Python tooling
sudo apt update
sudo apt install python3-pip python3-venv
# Clone project
git clone https://github.com/user/myapp.git
cd myapp
# Virtual environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run Gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app
Nginx configuration
아래 코드는 nginx를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# /etc/nginx/sites-available/myapp
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
다음은 간단한 bash 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
# Enable site
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
6. Practical tips
Deployment checklist
다음은 python를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
# Environment variables
# SECRET_KEY, DATABASE_URL, etc.
# DEBUG = False
app.config['DEBUG'] = False
# ALLOWED_HOSTS (Django)
ALLOWED_HOSTS = ['yourdomain.com']
# Static files
python manage.py collectstatic
# Database migrations
python manage.py migrate
# HTTPS
# Let's Encrypt, Cloudflare, etc.
Going deeper
Example: Gunicorn + systemd (minimal production pattern)
Assume the app is exposed as myapp.wsgi:app. This example binds to 127.0.0.1:8000 (not socket activation).
/etc/systemd/system/myapp.service:
다음은 ini를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
[Unit]
Description=My Gunicorn App
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
EnvironmentFile=/etc/myapp.env
ExecStart=/var/www/myapp/venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 myapp.wsgi:app
Restart=always
[Install]
WantedBy=multi-user.target
After deployment: sudo systemctl daemon-reload && sudo systemctl enable --now myapp.
Common mistakes
- Running with DEBUG=True in production and leaking secrets or tracebacks.
- Hard-coding virtualenv paths so deploy scripts break on the server.
- Relying on load balancers without health checks, so dead processes go unnoticed.
Safety notes
- Keep secrets in environment variables or a secret manager—never commit them to Git.
- Re-validate ALLOWED_HOSTS, CORS, and CSRF under your production profile.
How teams usually operate
- Put Nginx or Caddy in front for TLS termination.
- Ship logs to journald and onward to CloudWatch, ELK, or similar.
- For containers, prefer read-only root filesystems and non-root users.
Options at a glance
| Approach | Strengths |
|---|---|
| PaaS (Heroku, etc.) | Simple operations |
| VM + systemd | Control vs. cost tradeoff |
| Kubernetes | Large scale, many services |
Further reading
Summary
Key takeaways
- Gunicorn: production WSGI server
- Docker: reproducible environments
- Heroku: fast path to hosted apps
- AWS: flexible, often cost-effective at scale
- Nginx: reverse proxy in front of app workers
Next steps
- Pandas for data analysis
- Web scraping (future topics in the series)