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.
DockerfileFROM 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.
| Variable | Example value | Note |
|---|---|---|
| SECRET_KEY | django-insecure-replace-me | Any long random string. Never reuse your production key. |
| DEBUG | True | Fine for preview environments — always False in production. |
| ALLOWED_HOSTS | .previews.previewdrop.dev,localhost | The leading dot is a Django wildcard — covers every auto-generated preview subdomain. |
| DATABASE_URL | postgres://user:pass@host:5432/db | Point 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