Complete guide to deploy your Django project to Render & Vercel
Working Django application ready for deployment
Code hosted on GitHub, GitLab, or Bitbucket
requirements.txt with all dependencies
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
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
# 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/
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
]
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
Step-by-step guide for Render deployment
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
./build.shgunicorn myproject.wsgi:applicationimport 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'
Step-by-step guide for Vercel deployment
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"
}
]
}
Create build_files.sh:
#!/bin/bash # Install dependencies pip install -r requirements.txt # Collect static files python manage.py collectstatic --noinput --clear
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'])
npm i -g vercel vercel login vercel --prod
| 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 |
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"
Built-in PostgreSQL database service
Serverless PostgreSQL for modern apps
MySQL-compatible serverless database
CSS/JS files not loading after deployment
Can't connect to database
Application crashes with 500 error
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
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)
Step-by-step video guide
Serverless deployment tutorials
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! 🚀