← Back to Guides
Header image for blog post: How to deploy a Django app on Northflank
Daniel Adeboye
Published 5th September 2025

How to deploy a Django app on Northflank

Django is a powerful Python framework for building full-featured web applications. It comes with built-in tools like an ORM, admin panel, and authentication, making it ideal for complex projects.

In this guide, you’ll learn how to deploy a Django app with Docker on Northflank. We’ll create a project, configure it for production with PostgreSQL and WhiteNoise, and then deploy it using either a one-click template or your own Git repository.

Prerequisites

To follow along, you’ll need:

  1. Python 3 or later installed on your machine
  2. Basic knowledge of Python and Django
  3. Northflank account

What this tutorial covers

  1. Setting up a basic Django project
  2. Adding production essentials (WhiteNoise, PostgreSQL, secure settings)
  3. Preparing the project for containerization
  4. Deploying with Northflank
    • From a template
    • From a Git repository

1. Set up your Django project

💡 If you already have a Django app locally or on GitHub, skip to the next section.

Create a new project directory and navigate into it:

$ mkdir djangoapp
$ cd djangoapp

Set up a virtual environment and activate it:

$ python3 -m venv env
$ source env/bin/activate   # macOS/Linux
$ env\\Scripts\\activate      # Windows

Install Django:

(env)$ pip install django

Create a new Django project:

(env)$ django-admin startproject mydjproject .

Run the app locally with:

(env)$ python manage.py runserver

If successful, you’ll see output like this:

* Running on <http://127.0.0.1:8000>

Open your browser at http://127.0.0.1:8000 to check it works.

2. Add production essentials

When you run Django locally, everything works out of the box. But in production, there are three common problems:

  1. Django’s built-in server (runserver) is not secure or efficient enough for real traffic.
  2. Static files (CSS, JavaScript, images) and databases need proper configuration.
  3. Security settings (SECRET_KEYDEBUGALLOWED_HOSTS) must be updated.

To fix this, we’ll add WhiteNoise for static files and PostgreSQL for a reliable database.

1. Configure WhiteNoise to serve static files

By default, Django does not serve static files well in production. WhiteNoise is a small library that solves this problem by letting your Django app serve its own static files efficiently, without needing an external service like AWS S3.

Install it in your project’s root directory:

(env)$ pip install whitenoise

In mydjproject/settings.py, add the WhiteNoise middleware and configure your static files:

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",  # serve static files in production
    ...
]

STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

Now collect the static files into one folder:

(env)$ python manage.py collectstatic

Why this matters:

  • Without WhiteNoise, your CSS and JavaScript won’t load in production.
  • STATIC_ROOT tells Django where to put all your files.
  • WhiteNoise compresses and caches them so they load faster.

2. Configure PostgreSQL as your database

Django ships with SQLite by default, which is fine for testing but not reliable for production. PostgreSQL is the standard choice for Django apps in production because it is more powerful, scalable, and supported by most platforms (including Northflank).

Install the following packages in your project's directory:

(env)$ pip install psycopg2-binary dj-database-url
  • psycopg2-binary → lets Django talk to PostgreSQL.
  • dj-database-url → makes it easy to configure your database using a single environment variable (DATABASE_URL), which Northflank will provide when you connect a PostgreSQL addon.

Update mydjproject/settings.py with the following to replace the default SQLite database configuration with PostgreSQL:

import dj_database_url
import os

DATABASES = {
    "default": dj_database_url.config(
        default=os.getenv("DATABASE_URL", "sqlite:///db.sqlite3")
    )
}

Why this matters:

  • SQLite saves data in a single file on disk, which doesn’t work well in containers.
  • PostgreSQL runs as a separate service and keeps your data safe and persistent.
  • Using dj-database-url means your app automatically uses PostgreSQL in production, but you can still use SQLite locally if no database is configured.

(Optional) Use PostgreSQL locally

Replace "sqlite:///db.sqlite3" with your Postgres database URL (Deploy a database on Northflank using this guide).

Then run python manage.py migrate in your terminal to apply the database migrations.

Note: This is only for local development. When deploying on Northflank, you'll need to add the DATABASE_URL as an environment variable in your service configuration with the proper connection string value from your Postgres addon.

3. Secure settings for production

In your mydjproject/settings.py file, update the SECRET_KEY, DEBUG, and ALLOWED_HOSTS settings as follows:

SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "changeme")
DEBUG = os.getenv("DEBUG", "False") == "True"
ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",")

Why this matters:

  • Never hardcode your SECRET_KEY.
  • Always set DEBUG=False in production.
  • ALLOWED_HOSTS prevents host header attacks.

3. Prepare Django project for deployment on Northflank

Northflank runs your app inside a container. To do this smoothly, we’ll:

  • Add a production server (Gunicorn)
  • Create a requirements.txt
  • Write a Dockerfile

1. Install Gunicorn

Gunicorn is a lightweight WSGI server commonly used in production. Northflank will use it to run your app:

(env)$ pip install gunicorn

2. Create requirements.txt

Freeze your project dependencies so Northflank can install them during the build:

(env)$ pip freeze > requirements.txt

3. Add a Dockerfile

Northflank builds your container image using a Dockerfile. Create a new file called Dockerfile in your project root:

FROM python:3.11

ENV PYTHONUNBUFFERED=1

WORKDIR /app
COPY . ./

RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "mydjproject.wsgi:application"]

At this point, your app is container-ready.

4. Deploy to Northflank

You now have two ways to deploy on Northflank:

Option A: One-click deploy from a template

image - 2025-09-05T124742.114.png

  1. Visit the Django template on Northflank.
  2. Click Deploy.
  3. Northflank will:
    • Automatically create a project and service
    • Build your container from the template
    • Deploy and run the app
    • Add the starter code directly to your connected git repository
  4. Once it’s live, you’ll get a public URL where your Django app is accessible.

Option B: Deploy from your Git repository

If you’ve already created your Django project and pushed it to GitHub, GitLab, or Bitbucket, follow these steps:

1. Create a Northflank project

  1. Log in to your Northflank dashboard.
  2. Go to Projects → Create Project.
  3. Enter a project name (e.g.django-app).
  4. Choose where you'd like to deploy - either on Northflank cloud or on your own cloud.
  5. Select your preferred region.
  6. Click ’Create Project’.

image - 2025-09-05T124745.418.png

2. Create and configure a service

  1. Within your project, navigate to the Services tab at the top menu and click 'Create service'.
  2. Select the “Combined” service option that builds & deploys a git repo
  3. Enter a service name (e.g. django-backend).
  4. Select your Git provider and connect to the repository containing your Django project.
  5. Under Build options, select Dockerfile and specify the location (e.g. /Dockerfile if it's in the root directory).
  6. Under ’Networking’, add a port configuration:
    • Port: 8000 (Gunicorn default)
    • Protocol: HTTP
    • Public: enable
  7. Under Environment variables, add the following (Runtime variables):
    • DATABASE_URL → PostgreSQL connection string from your Northflank PostgreSQL addon (note: your app will default to SQLite if this isn't set)
    • DJANGO_SECRET_KEY → your Django project secret key
    • DEBUG → False (set True only for testing)
    • ALLOWED_HOSTS → your service domain (e.g. your-service.northflank.app)

💡 You can also store these inside a Secrets group in Northflank and link it to your service.

  1. Under Advanced → select Custom entrypoint & command.
    • Custom entrypoint: /bin/sh
    • Custom command: -c "python [manage.py](http://manage.py/) migrate --noinput && python [manage.py](http://manage.py/) collectstatic --noinput && gunicorn --bind 0.0.0.0:8000 mydjproject.wsgi:application"

💡 This ensures that every time your container starts, Django will automatically apply database migrations and collect static files before launching Gunicorn. That way, your app is always production-ready immediately after deployment.

  1. Review your settings and click ’Create service’.

image - 2025-09-05T124748.687.png

Northflank will then:

  • Clone your Git repository
  • Build the Docker image
  • Install dependencies from requirements.txt
  • Run your app with Gunicorn inside a container

Once the build completes successfully, you'll see a public service URL in the dashboard (like "p01--django--tqlt.code.run"). Open it to confirm your Django app is live 🚀.

image - 2025-09-05T124751.620.png

Next steps

Your Django app is now deployed on Northflank! 🎉

From here, you can:

Check the Northflank documentation for more advanced deployment workflows.

Share this article with your network
X