# Deploy Django with Postgres

Source: https://naijacloud.com/guides/deploy-django-postgres

This guide deploys a Django app to Naijacloud with a managed Postgres database. At the end you’ll have the app and the Django admin running over HTTPS at your own naijacloud.app address, with migrations applied every time the app starts and every push to your branch deploying automatically. The stack is Django 6, Gunicorn, WhiteNoise and Postgres 18, deployed from a GitHub repository.

_15 min · Beginner · Last verified 2026-10-11 · Stack: django, postgres_

**What you'll have at the end:** A Django app and the Django admin on your own naijacloud.app address, reading and writing to managed Postgres. Open /admin to sign in.

## Before you start

- A Django project in a GitHub repository. Starting fresh? Run `django-admin startproject mysite .` and push it.
- Python 3.12 or newer on your machine. Naijacloud builds Python apps on Python 3.12.
- A Naijacloud account. The free tier covers this guide: one web service and one database.

## Add the production packages

Django’s development server isn’t built for real traffic. Add Gunicorn to serve the app, WhiteNoise to serve static files, and the two packages that let Django reach Postgres through a single `DATABASE_URL`.

```sh
$ pip install django gunicorn whitenoise dj-database-url "psycopg[binary]"
$ pip freeze > requirements.txt
```

Naijacloud finds `requirements.txt`, recognises Django in it and installs it with `pip install -r requirements.txt`. Commit the file with the next step.

## Read settings from the environment

Open `mysite/settings.py`. Replace the hard-coded secret key, debug flag, hosts and database with values read from the environment, and give static files a folder WhiteNoise can serve.

```python title="mysite/settings.py"
import os
import dj_database_url

SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
DEBUG = os.environ.get("DJANGO_DEBUG", "False") == "True"
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")

# Naijacloud terminates HTTPS in front of your app
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

DATABASES = {"default": dj_database_url.config(conn_max_age=600)}

STATIC_ROOT = BASE_DIR / "staticfiles"
STORAGES = {
    "default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
    "staticfiles": {"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage"},
}
```

> **Note: Add the WhiteNoise middleware**
>
> In `MIDDLEWARE`, add `"whitenoise.middleware.WhiteNoiseMiddleware"` directly after `"django.middleware.security.SecurityMiddleware"`. Anywhere else and static files return 404.

From now on `manage.py` needs these variables too, so set them in your shell before running it locally: `export DJANGO_SECRET_KEY=dev DJANGO_DEBUG=True DATABASE_URL=sqlite:///db.sqlite3`.

## Create the admin user on start

You’ll never need to connect to the database from your laptop. Instead, a short management command creates your admin user from two variables the first time the app starts, and does nothing after that.

```sh
$ python manage.py startapp core
$ mkdir -p core/management/commands
```

Add `"core"` to `INSTALLED_APPS` in `mysite/settings.py`, then create the command:

```python title="core/management/commands/ensure_admin.py"
import os

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = "Create the admin user from environment variables, once."

    def handle(self, *args, **options):
        User = get_user_model()
        username = os.environ["DJANGO_ADMIN_USER"]
        if User.objects.filter(username=username).exists():
            return
        User.objects.create_superuser(
            username=username,
            email="",
            password=os.environ["DJANGO_ADMIN_PASSWORD"],
        )
        self.stdout.write(f"Created admin user {username}")
```

```sh
$ git add .
$ git commit -m "Prepare for Naijacloud"
$ git push
```

## Create the database

In the dashboard, open your project and choose **New service** → **Database**. Name it (for example `mysite-db`), pick **Postgres**, leave the connection details blank so they’re generated, choose the **Free** size and click **Create database**.

The next screen, **mysite-db is ready.**, shows the connection details once. Click **Reveal secrets** and copy the **Internal URL**. Your app uses it to reach the database over the private network.

> **Warning: The password is shown once on this page**
>
> Copy the Internal URL before you leave. You can find the host and port again on the database’s **Overview** tab, but keep the full URL somewhere safe until it’s saved on the web service in the next step.

## Create the web service

Back in the project, choose **New service** → **Web service**. Name it `mysite`; that name becomes your address, `mysite.naijacloud.app`. Under **Source**, choose **GitHub** and pick your repository and branch. Naijacloud detects Django and fills in the commands. Change them to these:

- **Build command**: `pip install -r requirements.txt`
- **Start command**: `python manage.py collectstatic --noinput && python manage.py migrate && python manage.py ensure_admin && gunicorn mysite.wsgi --bind 0.0.0.0:$PORT`

Everything runs in the start command because your variables are set when the app starts. The command collects static files, applies migrations and creates the admin user before Gunicorn begins serving, so the database is ready by the time the app answers. Naijacloud sets `PORT` for you.

## Set the variables

On the same screen, under **Environment variables**, click **Paste .env** and paste these five lines with your own values, then **Add variables**. Generate the secret key on your machine first:

```sh
$ python -c "import secrets; print(secrets.token_urlsafe(50))"
k7Qv2mX0f9Rz…
```

- **DATABASE_URL**: The Internal URL you copied from the database
- **DJANGO_SECRET_KEY**: The value you just generated
- **DJANGO_ALLOWED_HOSTS**: `.naijacloud.app`
- **DJANGO_ADMIN_USER**: The username you’ll sign in with
- **DJANGO_ADMIN_PASSWORD**: A long password. It’s only read the first time the app starts

> **Warning: Leave DJANGO_DEBUG unset**
>
> With debug on, Django shows your settings and stack traces to anyone who hits an error. Keep it for your machine.

## Deploy and sign in

Leave **Region** and **Instance type** as they are. **Free** is enough for this guide. Free apps may sleep when nobody visits for a while and wake on the next request; paid apps never sleep. Click **Create web service**, then **Open mysite**. The **Deploys** tab streams the build log. When the deploy goes live, the start command’s output appears in **Logs** under **Runtime**:

```sh title="Runtime log · mysite" nocopy
130 static files copied to '/app/staticfiles', 390 post-processed.
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  …
Created admin user ada
[INFO] Starting gunicorn 26.2.0
[INFO] Listening at: http://0.0.0.0:8000
```

Open `https://mysite.naijacloud.app/admin` and sign in with the username and password you set. From now on every push to your branch deploys, and the start command migrates the database first.

> **Warning: If the deploy fails with a KeyError**
>
> A variable is missing or misspelled. `KeyError: 'DJANGO_SECRET_KEY'` names the one to fix. Correct it under **Variables**, then click **Redeploy**.

> **Note: Prefer the terminal?**
>
> Install the CLI with `npm install -g @naijacloud/cli`, run `naijacloud login`, then `naijacloud redeploy mysite` rebuilds the latest commit on your branch without a push.

## Reference

- [Deploy a web service](https://naijacloud.com/docs/deploy/web-services.md)
- [Builds](https://naijacloud.com/docs/deploy/builds.md)
- [Connecting to a database](https://naijacloud.com/docs/databases/connecting.md)
- [Environment variables](https://naijacloud.com/docs/deploy/environment-variables.md)
- [Deploys and logs](https://naijacloud.com/docs/deploy/deploys-and-logs.md)

All guides: https://naijacloud.com/guides · Index for agents: https://naijacloud.com/llms.txt
