Skip to content

Deploy a Django app on Vercel

Deploy a Django app to Vercel with the Python runtime and Vercel Functions. Vercel detects manage.py and reads your WSGI or ASGI entrypoint from your project settings.

Create a Django project or use an existing one:

Initialize a new Django project with the Vercel CLI init command:

terminal
vc init django

This clones the Django example repository into a directory called django.

Vercel automatically detects Django projects by locating manage.py in your repository. Vercel then executes manage.py to discover your DJANGO_SETTINGS_MODULE and determines the entrypoint from WSGI_APPLICATION or ASGI_APPLICATION.

For a WSGI app (the default), configure your settings and wsgi.py:

myproject/settings.py
WSGI_APPLICATION = 'myproject.wsgi.application'
myproject/wsgi.py
import os
 
from django.core.wsgi import get_wsgi_application
 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
 
application = get_wsgi_application()

For an ASGI app, set ASGI_APPLICATION instead and define application in asgi.py:

myproject/settings.py
ASGI_APPLICATION = 'myproject.asgi.application'
myproject/asgi.py
import os
 
from django.core.asgi import get_asgi_application
 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
 
application = get_asgi_application()

When both ASGI_APPLICATION and WSGI_APPLICATION are set in your Django settings, Vercel uses the ASGI entrypoint.

To point Vercel to a Django app in a custom module, set tool.vercel.entrypoint in pyproject.toml:

pyproject.toml
[tool.vercel]
entrypoint = "myproject.wsgi:application"

The tool.vercel.entrypoint value tells Vercel to look for a WSGI instance named application in ./myproject/wsgi.py.

The build property in [tool.vercel.scripts] defines the Build Command for Django deployments. It runs after dependencies are installed and before Vercel deploys your application:

pyproject.toml
[tool.vercel.scripts]
build = "python build.py"

For example:

build.py
def main():
    print("Running build command...")
    with open("build.txt", "w") as f:
        f.write("BUILD_COMMAND")
 
if __name__ == "__main__":
    main()

A Build Command defined in vercel.json or in the Project Settings dashboard takes precedence over a build script in pyproject.toml.

There is no need to call collectstatic in a build script. Vercel runs it automatically. See Serving static assets for more details.

Use vercel dev to run your application locally:

terminal
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
vercel dev
Minimum CLI version required: 50.38.0

Deploy the project by connecting your Git repository or by using the Vercel CLI:

terminal
vc deploy
Minimum CLI version required: 50.38.0

When your Django project has STATIC_ROOT configured, Vercel automatically runs collectstatic during the build and serves the collected files from the Vercel CDN. Files are served at STATIC_URL (Django's default is /static/).

No additional configuration is needed. {% static %} template tags work in both production and local development with vercel dev.

Supported storage backends:

  • StaticFilesStorage (default)
  • ManifestStaticFilesStorage
  • WhiteNoise CompressedManifestStaticFilesStorage

If Vercel detects django-storages as the storage backend, it runs collectstatic with your original settings so files are uploaded directly to your storage provider during the build. Set any required environment variables for your storage provider in your Vercel project environment variables.

WhiteNoise is compatible with Vercel. In production, static files are served from the CDN. WhiteNoise is only active when running locally with vercel dev.

If WHITENOISE_USE_FINDERS = True is set, then STATIC_ROOT is not required and Vercel will collect static files directly from your app directories.

When you add a database or other integration to your Vercel project, Vercel automatically sets environment variables like DATABASE_URL. You can access these in your Django settings through os.environ. See environment variables for more details.

For example, to configure a PostgreSQL database using DATABASE_URL:

myproject/settings.py
import os
import urllib.parse
 
if os.environ.get("DATABASE_URL"):
    url = urllib.parse.urlparse(os.environ["DATABASE_URL"])
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            "NAME": url.path.lstrip("/"),
            "USER": url.username,
            "PASSWORD": url.password,
            "HOST": url.hostname,
            "PORT": url.port,
        }
    }
else:
    # Fall back to SQLite for local development
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR / "db.sqlite3",
        }
    }

To use environment variables locally (for example, to run migrations), first pull them with vercel pull:

terminal
vercel pull

This saves your environment variables to .env.local. Then load them in manage.py using dotenv or django-environ:

manage.py (dotenv)
from dotenv import load_dotenv
load_dotenv(".env.local")
manage.py (django-environ)
import environ
environ.Env.read_env(".env.local")

Never commit .env.local to version control. Add it to your .gitignore file to avoid exposing secrets.

When you deploy a Django app to Vercel, it becomes a single Vercel Function. Vercel uses Fluid compute by default, so the function scales with traffic.

To configure that function, add an entry to the functions object in vercel.json keyed by your resolved entrypoint file. For example, to let a WSGI app defined in myproject/wsgi.py run for up to 60 seconds, set maxDuration:

vercel.json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "functions": {
    "myproject/wsgi.py": {
      "maxDuration": 60
    }
  }
}

For an ASGI app, key the entry on myproject/asgi.py instead. If your manage.py lives in a subdirectory, prefix the key with that directory (for example backend/myproject/wsgi.py). For more options, see Configuring functions and the functions property.

Use Django Channels to add WebSocket consumers and routing to your Django ASGI application. Vercel serves the WebSocket connection from the same Vercel Function as your Django application.

Follow the steps below to get started with WebSockets and Django.

  1. Add Django and channels to your pyproject.toml:

    pyproject.toml
    [project]
    name = "my-django-app"
    version = "0.1.0"
    requires-python = ">=3.12"
    dependencies = [
        "channels>=4.2",
        "Django>=5.1",
    ]

    Install the dependencies from pyproject.toml with uv:

    terminal
    uv sync
  2. myproject/consumers.py
    from channels.generic.websocket import AsyncWebsocketConsumer
     
    class EchoConsumer(AsyncWebsocketConsumer):
        async def connect(self):
            await self.accept()
     
        async def receive(self, text_data=None, bytes_data=None):
            if text_data is not None:
                await self.send(text_data=text_data)
            elif bytes_data is not None:
                await self.send(bytes_data=bytes_data)
  3. Route WebSocket connections to the consumer from your ASGI entrypoint:

    myproject/asgi.py
    import os
     
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
     
    from django.core.asgi import get_asgi_application
     
    # Initialize Django before importing code that may use the app registry.
    django_asgi_application = get_asgi_application()
     
    from channels.routing import ProtocolTypeRouter, URLRouter
    from django.urls import path
     
    from myproject.consumers import EchoConsumer
     
    application = ProtocolTypeRouter(
        {
            "http": django_asgi_application,
            "websocket": URLRouter(
                [
                    path("api/ws", EchoConsumer.as_asgi()),
                ]
            ),
        }
    )
  4. Set ASGI_APPLICATION in your Django settings so Vercel loads the ASGI entrypoint:

    myproject/settings.py
    ASGI_APPLICATION = "myproject.asgi.application"

For group broadcasts across Vercel Function instances, configure an external channel layer. InMemoryChannelLayer only coordinates connections within one function instance. Learn more about managing persistent state, handling reconnects, and WebSocket limits.

All Vercel Functions limitations apply to Django applications, including:

  • Application size: The Django application becomes a single bundle, which has a standard bundle size limit of 500MB. Large Functions support Python bundles up to 5GB on Fluid compute when enabled (public beta).

For more about deploying Django on Vercel, see:

Last updated July 24, 2026

Was this helpful?