Tutorial Web Development
Django development setup with uv and Docker

Modern Django development setup with uv and Docker

Setting up a Python web environment often involves legacy tooling. This guide walks you through a streamlined approach using Docker, Django, uv, and Just. This setup skips pip, virtualenv, and requirements files, using uv for dependency management and lockfiles without requiring manual environment activation. It also replaces Makefiles with Just for simpler command shortcuts.

Initializing the project with uv

To get started, create a new uv project. Run the following command in your terminal to initialize the directory structure:

uv init --no-package django-project
cd django-project

Next, install django and psycopg to handle the web framework and PostgreSQL database connectivity:

uv add "django==5.2.*" psycopg[binary]

With the core packages installed, start your new Django project structure by running:

uv run django-admin startproject config .

Automating tasks with Just and Docker

Instead of relying on a traditional Makefile, use a Justfile to manage local development commands. Create a Justfile and add this code:

export UV_ENV_FILE := ".env"

manage := "uv run manage.py"

manage *args:
    @{{manage}} {{args}}

migrate *args:
    @{{manage}} migrate {{args}}

createsuperuser *args:
    @{{manage}} createsuperuser {{args}}

runserver:
    @{{manage}} runserver

To manage the database container, create a compose.yaml file in your project root and add these lines:

services:
  postgresql:
    image: postgres:18-alpine
    environment:
      POSTGRES_DB: django_project
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - 5432:5432
    volumes:
      - pgdata:/var/lib/postgresql

volumes:
  pgdata:

Spin up your postgresql service in the background by executing this command:

docker compose up -d

Configuring database settings and running migrations

To connect your Django application to the PostgreSQL container, import os and update the DATABASES dictionary in your config/settings.py file:

import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv("DATABASE_NAME"),
        'USER': os.getenv("DATABASE_USER"),
        'PASSWORD': os.getenv("DATABASE_PASSWORD"),
        'HOST': os.getenv('DATABASE_HOST'),
        'PORT': os.getenv("DATABASE_PORT"),
    },
}

Next, create a .env file in your root directory to store database credentials and environment secrets:

DATABASE_NAME=django_project
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres
DATABASE_HOST=localhost
DATABASE_PORT=5432

With your environment configured, make your initial database migrations using uv:

just migrate

Create a superuser account with your username and password to access the admin dashboard:

just createsuperuser

Finally, start the Django development server using your task runner:

just runserver

Open localhost:8000 to see the welcome page. You should see the Django success screen confirming that the development server managed by uv started without errors.

Django 5.2 success screen at localhost:8000 showing the default rocket, confirming that the local development web server managed by uv started successfully without errors.

Next, access localhost:8000/admin/ to log into the admin panel with your superuser credentials. This confirms your host environment connected to PostgreSQL in Docker and that your migrations ran properly.

Django admin dashboard at localhost:8000/admin/ logged in as superuser. Confirms the host environment connected to PostgreSQL in Docker and migrations ran properly.