# How to Deploy a Django App to Production (2026 Guide)

Deploy Django with Gunicorn, PostgreSQL, WhiteNoise static files and automatic migrations: production settings, ALLOWED_HOSTS, CSRF and a one-command deploy.

URL: https://blog.dockhosting.dev/deploy-django-app-production
Published: 2026-11-01 · Updated: 2026-11-01 · Author: Doughmi ILYAS

## Summary

- Production Django needs four settings from the environment: SECRET_KEY, DEBUG=False, ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS.
- Read the database from DATABASE_URL with dj-database-url, and serve static files with WhiteNoise.
- On DockHosting, Gunicorn is configured for you and manage.py migrate runs automatically before traffic switches.

ort const meta = {
  title: "How to Deploy a Django App to Production (2026 Guide)",
  seoTitle: "How to Deploy Django to Production (2026 Guide)",
  description:
    "Deploy Django with Gunicorn, PostgreSQL, WhiteNoise static files and automatic migrations: production settings, ALLOWED_HOSTS, CSRF and a one-command deploy.",
  date: "2026-11-01",
  category: "Guides",
  tags: ["Django", "Python", "PostgreSQL", "Deployment", "Tutorial"],
  stack: ["django", "gunicorn", "postgresql"],
  command: "dock deploy",
  takeaways: [
    "Production Django needs four settings from the environment: SECRET_KEY, DEBUG=False, ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS.",
    "Read the database from DATABASE_URL with dj-database-url, and serve static files with WhiteNoise.",
    "On DockHosting, Gunicorn is configured for you and manage.py migrate runs automatically before traffic switches.",
  ],
  faq: [
    {
      q: "Do I need a Procfile or Dockerfile to deploy Django?",
      a: "No. DockHosting detects Django from manage.py, installs dependencies with pip (requirements.txt) or Poetry (pyproject.toml), runs Gunicorn workers and runs migrate before the new release takes traffic.",
    },
    {
      q: "Which Python versions are supported?",
      a: "Python 3.11 and 3.12.",
    },
    {
      q: "Why do I get 'CSRF verification failed' in production?",
      a: "Since Django 4.0, CSRF checks the Origin header against CSRF_TRUSTED_ORIGINS, which must include the scheme, for example https://myapp.dockhosting.cloud. Add every domain your site is served from.",
    },
    {
      q: "Why are my static files (CSS, admin styles) missing?",
      a: "With DEBUG=False, Django no longer serves static files. Add WhiteNoise middleware and make sure collectstatic runs during the build.",
    },
  ],
};

To deploy a Django app to production you need five things: settings read from the environment (`SECRET_KEY`, `DEBUG=False`, `ALLOWED_HOSTS`, `CSRF_TRUSTED_ORIGINS`), a WSGI server (Gunicorn), a production database read from `DATABASE_URL` with dj-database-url, static files served by WhiteNoise after `collectstatic`, and migrations that run before traffic switches. On DockHosting, Gunicorn and `manage.py migrate` are handled automatically, so the deploy itself is one command: `dock deploy`.

> **Python versions:** DockHosting runs Python 3.11 and 3.12. Django 6 requires Python 3.12 or newer, so Django 6 projects run on 3.12.

## 1. Production settings from the environment

Hard-coded secrets and `DEBUG = True` are the two classic Django deploy mistakes. Read both from the environment:

```python
# settings.py
import os
import dj_database_url

SECRET_KEY = os.environ["SECRET_KEY"]
DEBUG = os.environ.get("DEBUG", "False") == "True"

ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "").split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS if h]

DATABASES = {"default": dj_database_url.config(conn_max_age=600)}
```

Generate a strong key once and store it as a secret:

```bash
python -c "import secrets; print(secrets.token_urlsafe(50))"
```

> Never deploy with `DEBUG = True`. Debug pages show your settings, environment and source code to anyone who triggers an error.

## 2. Static files with WhiteNoise

With `DEBUG=False`, Django stops serving CSS and JavaScript (including the admin's). [WhiteNoise](https://whitenoise.readthedocs.io/) serves them efficiently from your app:

```python
# settings.py
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",  # right after SecurityMiddleware
    # …
]

STATIC_ROOT = BASE_DIR / "staticfiles"
STORAGES = {
    "default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
    "staticfiles": {"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage"},
}
```

Files have to be collected at build time. Add `collectstatic` to your project's build command in the dashboard:

```bash
python manage.py collectstatic --noinput
```

## 3. Dependencies

```text
# requirements.txt
django
gunicorn
dj-database-url
psycopg[binary]
whitenoise
```

Pin versions (`pip freeze > requirements.txt`) so production installs exactly what you tested. Poetry users can keep `pyproject.toml`: it's detected too.

## 4. Deploy

```bash
curl -fsSL https://cli.dockhosting.dev/install.sh | sh   # Windows: irm https://cli.dockhosting.dev/install.ps1 | iex
dock login
dock deploy
```

What happens:

1. `manage.py` marks the project as Django, on Python 3.11 or 3.12.
2. Dependencies are installed with pip or Poetry.
3. **Gunicorn** workers are configured for you, so you don't need a Procfile.
4. `python manage.py migrate` **runs automatically before traffic switches** to the new release, so your schema is never behind your code.
5. You get `https://<project>.dockhosting.cloud` with automatic HTTPS.

Set `SECRET_KEY` and `ALLOWED_HOSTS` (for example `myapp.dockhosting.cloud`) in the project's environment variables.

## 5. Add PostgreSQL

Create a managed **PostgreSQL** database in the dashboard and attach it to the project. `DATABASE_URL` is injected over a private network, and the `dj_database_url.config()` line above picks it up with no code changes. Create your admin user from your machine through public database access (Hobby and up), or with a data migration.

Need Redis for caching or Celery? Attach managed Redis and read `REDIS_URL`.

## 6. Production checklist

| Setting | Value |
|---|---|
| `DEBUG` | `False` |
| `SECRET_KEY` | From the environment, 50+ random characters |
| `ALLOWED_HOSTS` | Your `.dockhosting.cloud` host and custom domains |
| `CSRF_TRUSTED_ORIGINS` | The same hosts, with `https://` |
| `SECURE_PROXY_SSL_HEADER` | `("HTTP_X_FORWARDED_PROTO", "https")` if you use `SECURE_SSL_REDIRECT` |
| Static files | WhiteNoise + `collectstatic` in the build |

Run `python manage.py check --deploy` locally. It flags most of these for you.

## Troubleshooting

- **`DisallowedHost`**: add the host to `ALLOWED_HOSTS`.
- **CSRF failed on login or forms**: add the `https://` origin to `CSRF_TRUSTED_ORIGINS`.
- **502 after deploy**: see [8 causes of a 502 and how to fix them](/fix-502-bad-gateway-after-deploy).

Prefer async APIs? See [deploying FastAPI](/deploy-fastapi-app).

## FAQ

### Do I need a Procfile or Dockerfile to deploy Django?

No. DockHosting detects Django from manage.py, installs dependencies with pip (requirements.txt) or Poetry (pyproject.toml), runs Gunicorn workers and runs migrate before the new release takes traffic.

### Which Python versions are supported?

Python 3.11 and 3.12.

### Why do I get 'CSRF verification failed' in production?

Since Django 4.0, CSRF checks the Origin header against CSRF_TRUSTED_ORIGINS, which must include the scheme, for example https://myapp.dockhosting.cloud. Add every domain your site is served from.

### Why are my static files (CSS, admin styles) missing?

With DEBUG=False, Django no longer serves static files. Add WhiteNoise middleware and make sure collectstatic runs during the build.
