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 ]
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.sh
gunicorn myproject.wsgi:application
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
SECRET_KEY
Your Django secret key
DEBUG
False
DATABASE_URL
PostgreSQL connection string
ALLOWED_HOSTS
yourdomain.com,.onrender.com
PYTHON_VERSION
3.11.6
SECRET_KEY
Your Django secret key
DEBUG
False
DATABASE_URL
External database connection
ALLOWED_HOSTS
yourdomain.com,.vercel.app
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