From Zero to Live β A complete case study walkthrough of a modern production-ready Django deployment pipeline.
π Introduction
If you're a developer or freelancer deploying Django projects for clients or yourself, this guide shows how to achieve a production-grade, secure, and scalable deployment on a tight budget. We'll use an EC2 instance, Docker, Nginx, Gunicorn, Certbot, and PostgreSQL.
Use Case: Perfect for personal portfolios, client projects, or scalable MVPs.
π Step 1: Connect to Your EC2 Server
SSH into your EC2 instance using your key:
ssh -i path-to-key.pem ec2-user@your-ec2-ip
Make sure your domain points to your EC2's public IP via A record in your domain DNS settings.
π Step 2: Project Directory Structure
project-root/
βββ docker-compose.yml
βββ Dockerfile
βββ nginx/
β βββ default.conf
βββ certbot/
β βββ www/
β βββ conf/
βββ .env
βββ portfolio/ # Django project folder
π³ Step 3: Create Dockerfile for Django
FROM python:3.10-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "portfolio.wsgi:application", "--bind", "0.0.0.0:8000"]
π Step 4: Setup HTTP with Nginx
server {
listen 80;
server_name your-domain.com www.your-domain.com;
location /static/ {
alias /app/static/;
}
location / {
proxy_pass http://portfolio-web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
π¦ Step 5: Docker Compose for Services
version: "3.9"
services:
portfolio-web:
build: .
volumes:
- .:/app
expose:
- "8000"
env_file:
- .env
nginx-container:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
depends_on:
- portfolio-web
π Step 6: Stop Services & Get SSL
Stop containers to free port 80:
docker-compose down
Then run Certbot:
docker run -it --rm \
-v "$(pwd)/certbot/www:/var/www/certbot" \
-v "$(pwd)/certbot/conf:/etc/letsencrypt" \
certbot/certbot certonly \
--webroot --webroot-path=/var/www/certbot \
--email your-email@example.com \
--agree-tos --no-eff-email \
-d your-domain.com -d www.your-domain.com
π Step 7: Add HTTPS Support in Nginx
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
location /static/ {
alias /app/static/;
}
location / {
proxy_pass http://portfolio-web:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
β»οΈ Step 8: Update Compose for Auto Renewal
certbot:
image: certbot/certbot
volumes:
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
entrypoint: /bin/sh -c
command: "trap exit TERM; while :; do sleep 6h & wait $${!}; certbot renew; done"
β Final Launch
docker-compose up -d --build
π‘ Bonus: Validate SSL Renewal
docker-compose run --rm certbot renew --dry-run
Written by an AI + Web Dev + Automation Expert π | Looking to build or deploy your project? Hire Me
No comments yet. Be the first to share your thoughts!