Django Deployment

Complete guide to deploy your Django project to Render & Vercel

Deployment Overview

Render

Perfect for full-stack Django applications with database and static files.

  • Free tier available
  • PostgreSQL database
  • Automatic deployments
  • SSL certificates

Vercel

Optimized for frontend and serverless Django applications.

  • Edge network
  • Serverless functions
  • Fast deployments
  • GitHub integration

Prerequisites

Django Project

Working Django application ready for deployment

Git Repository

Code hosted on GitHub, GitLab, or Bitbucket

Requirements File

requirements.txt with all dependencies

Essential Files

requirements.txt

Django==4.2.7
gunicorn==21.2.0
whitenoise==6.6.0
psycopg2-binary==2.9.9
python-decouple==3.8
dj-database-url==2.1.0
django-cors-headers==4.3.1
Pillow==10.1.0
django-crispy-forms==2.1
crispy-tailwind==0.5.0

.env

SECRET_KEY=your-secret-key-here
DEBUG=False
DATABASE_URL=postgresql://user:pass@host:port/db
ALLOWED_HOSTS=yourdomain.com,.onrender.com,.vercel.app
STATIC_URL=/static/
MEDIA_URL=/media/
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password

.gitignore

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/

# Django
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
media/

# Environment variables
.env
.env.local
.env.production

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Static files
/staticfiles/
/static/
collected-static/

settings.py (Key Parts)

import os
from decouple import config
import dj_database_url

# Security
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=lambda v: [s.strip() for s in v.split(',')])

# Database
DATABASES = {
    'default': dj_database_url.config(
        default=config('DATABASE_URL')
    )
}

# Static files
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# Middleware
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ... other middleware
]

Gunicorn & WhiteNoise Configuration

For production, use Gunicorn as the WSGI HTTP server and WhiteNoise for serving static files efficiently:

# Install dependencies
pip install gunicorn whitenoise

# In settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ... other middleware
]

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

# Start Gunicorn
gunicorn Blog.wsgi:application --bind 0.0.0.0:8000

Deploy to Render

Step-by-step guide for Render deployment

1

Create Render Account & Connect Repository

  • • Sign up at render.com
  • • Connect your GitHub/GitLab account
  • • Select your Django project repository
2

Create Build Script

Create build.sh in your project root:

#!/usr/bin/env bash
# exit on error
set -o errexit

pip install -r requirements.txt

python manage.py collectstatic --no-input
python manage.py migrate
3

Configure Web Service

Service Settings:

  • Environment: Python 3
  • Build Command: ./build.sh
  • Start Command: gunicorn myproject.wsgi:application
  • Auto-Deploy: Yes

Environment Variables:

  • • SECRET_KEY
  • • DEBUG=False
  • • DATABASE_URL
  • • PYTHON_VERSION=3.11.6
4

Create PostgreSQL Database

  • • Go to Render Dashboard → Create → PostgreSQL
  • • Choose a name for your database
  • • Copy the External Database URL
  • • Add it as DATABASE_URL environment variable in your web service

Production Settings Configuration

settings.py Production Configuration

import dj_database_url
from decouple import config
from pathlib import Path
import os

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = ['.vercel.app', '.onrender.com', 'localhost']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

DATABASE_URL = config('DATABASE_URL', default=None)
if DATABASE_URL:
    DATABASE_URL = DATABASE_URL.strip()
    DATABASES['default'] = dj_database_url.parse(DATABASE_URL, conn_max_age=600, ssl_require=True)

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'

Deploy to Vercel

Step-by-step guide for Vercel deployment

1

Create vercel.json Configuration

Create vercel.json in your project root:

{
  "version": 2,
  "builds": [
    {
      "src": "myproject/wsgi.py",
      "use": "@vercel/python",
      "config": { "maxLambdaSize": "15mb", "runtime": "python3.9" }
    },
    {
      "src": "build_files.sh",
      "use": "@vercel/static-build",
      "config": {
        "distDir": "staticfiles_build"
      }
    }
  ],
  "routes": [
    {
      "src": "/static/(.*)",
      "dest": "/static/$1"
    },
    {
      "src": "/(.*)",
      "dest": "myproject/wsgi.py"
    }
  ]
}
2

Create Build Script

Create build_files.sh:

#!/bin/bash

# Install dependencies
pip install -r requirements.txt

# Collect static files
python manage.py collectstatic --noinput --clear
3

Update Settings for Vercel

Add to your settings.py:

# Vercel specific settings
import os

# Static files
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles_build', 'static')

# Database (use external service like PlanetScale, Neon, etc.)
if 'DATABASE_URL' in os.environ:
    import dj_database_url
    DATABASES['default'] = dj_database_url.parse(os.environ['DATABASE_URL'])

# Vercel specific
if os.environ.get('VERCEL_ENV'):
    ALLOWED_HOSTS.extend(['.vercel.app', '.now.sh'])
4

Deploy to Vercel

Via Vercel CLI:

npm i -g vercel
vercel login
vercel --prod

Via Vercel Dashboard:

  • • Visit vercel.com
  • • Import Git Repository
  • • Configure environment variables
  • • Deploy

Complete Environment Variables Reference

Variable Description Required
SECRET_KEY Django secret key for cryptographic signing Yes
DEBUG Set to False in production for security Yes
DATABASE_URL PostgreSQL connection string Yes
EMAIL_HOST_USER Your SMTP email address for sending emails Optional
EMAIL_HOST_PASSWORD Your SMTP password or app-specific password Optional
POSTS_PER_PAGE Number of posts per page for pagination Optional
FILE_UPLOAD_MAX_MEMORY_SIZE Maximum file upload size in bytes Optional

Complete .env File Example

Production .env Template

SECRET_KEY="your-secret-key-here-make-it-long-and-random"
DEBUG=False
DATABASE_URL="postgresql://user:password@host:5432/dbname"
ALLOWED_HOSTS="yourdomain.com,.onrender.com,.vercel.app"

# Email Configuration (Optional)
EMAIL_HOST_USER="your-email@example.com"
EMAIL_HOST_PASSWORD="your-email-app-password"
EMAIL_HOST="smtp.gmail.com"
EMAIL_PORT=587
EMAIL_USE_TLS=True

# Application Settings (Optional)
POSTS_PER_PAGE=9
FILE_UPLOAD_MAX_MEMORY_SIZE=5242880

# Static & Media Files
STATIC_URL="/static/"
MEDIA_URL="/media/"

# Security Headers
SECURE_BROWSER_XSS_FILTER=True
SECURE_CONTENT_TYPE_NOSNIFF=True
X_FRAME_OPTIONS="DENY"

Database Options

Render PostgreSQL

Built-in PostgreSQL database service

  • • Free tier: 90 days
  • • 1GB storage
  • • Automatic backups
  • • Easy integration

Neon Database

Serverless PostgreSQL for modern apps

  • • Always free tier
  • • 512MB storage
  • • Branching support
  • • Auto-scaling

PlanetScale

MySQL-compatible serverless database

  • • Free tier available
  • • Branching workflow
  • • Global replication
  • • Schema migrations

Common Issues & Solutions

Static Files Not Loading

Problem:

CSS/JS files not loading after deployment

Solution:

  • • Check STATIC_ROOT and STATIC_URL settings
  • • Run python manage.py collectstatic
  • • Ensure WhiteNoise is properly configured

Database Connection Issues

Problem:

Can't connect to database

Solution:

  • • Verify DATABASE_URL format
  • • Check database credentials
  • • Ensure psycopg2-binary is installed
  • • Run migrations after deployment

Internal Server Error (500)

Problem:

Application crashes with 500 error

Solution:

  • • Check application logs
  • • Verify all environment variables
  • • Ensure DEBUG=False in production
  • • Check ALLOWED_HOSTS setting

WSGI Configuration

wsgi.py (Production Ready)

import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

application = get_wsgi_application()

# Vercel specific
app = application

urls.py (Static Files)

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    # your app urls
]

# Serve static and media files in production
if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
else:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Deployment Best Practices

Security

  • • Use environment variables
  • • Set DEBUG=False
  • • Configure ALLOWED_HOSTS
  • • Use HTTPS in production

Performance

  • • Use WhiteNoise for static files
  • • Enable gzip compression
  • • Optimize database queries
  • • Use CDN for media files

Development

  • • Use version control (Git)
  • • Separate settings files
  • • Test before deployment
  • • Monitor application logs

Database

  • • Regular backups
  • • Use migrations properly
  • • Index frequently queried fields
  • • Monitor database performance

Monitoring

  • • Set up error tracking
  • • Monitor uptime
  • • Track performance metrics
  • • Set up alerts

CI/CD

  • • Automated deployments
  • • Run tests before deploy
  • • Use staging environment
  • • Rollback capabilities

Video Tutorials

Additional Resources

Quick Commands Cheat Sheet

Development Commands

# Create virtual environment
python -m venv venv
# Activate virtual environment
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Generate requirements
pip freeze > requirements.txt

Deployment Commands

# Collect static files
python manage.py collectstatic --noinput
# Run migrations
python manage.py migrate
# Create superuser
python manage.py createsuperuser
# Test production server
gunicorn myproject.wsgi:application

Ready to Deploy!

You now have everything you need to deploy your Django application to both Render and Vercel. Choose the platform that best fits your project needs and follow the step-by-step guides above.

Need help? Check out the troubleshooting section above or watch the video tutorials.

Happy deploying! 🚀