In this post I will make an example how to setup a Django and the required infrastructure using docker compose for the following components:
I will show to make this setup using uv. The uv tool is somehow recent (release in 2024), I usually apologist of using old and battle tested tools, although the benefits of using uv (uv install guide) vastly outweight other similar tools like pip or open to manage dependencies, python version, making virtual python environments, etc.
To start a Django app run the command uvx --from django django-admin startproject main project_folder.
After this command you should have these files on the project_folder:
project_folder
├── main
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Init project.toml and install required dependencies:
uv init: This creates the project.toml file.uv add django psycopg2-binary python-dotenv gunicorn: This install dependencies (Note: do not install psycopg2-binary if you do not intend to use postgres database, by default django uses sqlite, you can start with just that).uv add --dev django-debug-toolbar mypy django-stubs black django-stubs-ext ruff: Install useful packages for development.mypy.ini with the following contents:
[mypy]
plugins =
mypy_django_plugin.main
ignore_missing_imports = True
[mypy.plugins.django-stubs]
django_settings_module = "main.settings"
project.toml file:[tool.ruff]
fix = true
unsafe-fixes = true
line-length = 100
extend-exclude = ["migrations", "settings_dev.py", "settings_prd.py", "manage.py",]
show-fixes = true
[tool.ruff.lint]
extend-select = ["E", "F", "I"]
unfixable = ["F841"]
You can run now the following commands to lint and format the code:
uv run -m ruff format: Formats the code.uv run -m ruff check --fix: Linter.uv run -m mypy .: Check typing.Create the docker-compose.yaml file with the following content:
version: "3.9"
services:
db:
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -q -h 127.0.0.1 -U $$POSTGRES_USER -d $$POSTGRES_DB || exit 1"]
interval: 2s
timeout: 5s
retries: 12
start_period: 2s
redis:
image: redis
ports:
- "6379:6379"
mailhog:
image: mailhog/mailhog
ports:
- "1025:1025"
- "8025:8025"
This docker compose setup the following components:
To use the database and mailhog create the following settings on main/settings.py:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "127.0.0.1",
}
}
EMAIL_HOST ="127.0.0.1"
EMAIL_PORT = "1025"
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
The emails you send can bee seen on the mailhog web interface at 127.0.0.1:8025.
Now run the migrations with uv run manage.py migrate and run the project with uv run manage.py runserver. You should be able to access you web app through 127.0.0.1:8000.