PreviewDrop for Django

Deploy previews for Django apps

Push a branch, get a live preview URL. PreviewDrop builds your Django container and posts the link to the pull request in under 60 seconds — no CI scripts, no serverless adapters.

TL;DR
Add a Dockerfile, connect your repo, push. PreviewDrop detects the push, builds the image, runs your migrations, and posts a TLS-terminated preview URL to the PR. Gunicorn runs exactly as it does in production — no Django-to-Lambda adapters, no 10-second function limits on views, no cold starts.

Dockerfile

Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.

Dockerfile
FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN python manage.py collectstatic --noinput EXPOSE 8000 # Replace "myapp" with the folder that contains your wsgi.py CMD sh -c "python manage.py migrate --noinput && gunicorn myapp.wsgi:application --bind 0.0.0.0:${PORT:-8000} --workers 2"

Environment variables

Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.

VariableExample valueNote
SECRET_KEYdjango-insecure-replace-meAny long random string. Never reuse your production key.
DEBUGTrueFine for preview environments — always False in production.
ALLOWED_HOSTS.previews.previewdrop.dev,localhostThe leading dot is a Django wildcard — covers every auto-generated preview subdomain.
DATABASE_URLpostgres://user:pass@host:5432/dbPoint at a shared dev DB, or omit to use SQLite (fine for UI-only previews).

Common gotchas

ALLOWED_HOSTS must include .previews.previewdrop.dev

Django returns a 400 for requests from unknown hosts. Set ALLOWED_HOSTS=.previews.previewdrop.dev,localhost in your project variables. The leading dot is a Django wildcard that matches every auto-generated preview subdomain without needing to know the URL in advance.

Replace "myapp" in the CMD with your project name

The Dockerfile CMD uses myapp.wsgi:application. Replace myapp with the name of the Django project directory that contains your wsgi.py — usually the same as the root project folder name.

gunicorn must be in requirements.txt

The image only installs what's in requirements.txt. If gunicorn isn't listed there the CMD will fail at startup. Add gunicorn>=21.2 if it's missing.

Static files: run collectstatic at build time

The Dockerfile runs collectstatic during the build so assets are baked into the image. To serve them without a CDN, add whitenoise to MIDDLEWARE and set the whitenoise storage backend in STATICFILES_STORAGE.

Why not Vercel or Netlify?

Vercel doesn't run Django natively. Community adapters exist that wrap WSGI in a Lambda function, but you lose long-running request support, Celery workers, and manage.py access. Netlify has the same constraint — their Functions runtime is Node/Deno/Go, not Python WSGI. PreviewDrop runs your Dockerfile directly: Gunicorn, background workers, migrations at startup — the same container shape as your production environment, used as a PR deploy preview.

Preview your Django app in 5 minutes

Connect a repo, push a branch, get a URL. No credit card, no trial clock.

Start free