A production-ready Django project template. Clone it, copy .env.example to .env, and start building.
| Feature | Details |
|---|---|
| Split settings | development, production, testing — switch by setting DJANGO_ENV |
| Custom User model | Pre-wired so you can add fields anytime without migration headaches |
| SQLite in dev | No database setup needed for local development |
| PostgreSQL in production | Runs as a Docker container from the official Postgres image |
| Redis + Celery | Task queue and broker running as Docker containers |
| Docker setup | docker-compose.yml for dev, docker-compose.prod.yml for production |
| Nginx | Reverse proxy in production; serves static and media files directly |
| Logging | Console everywhere; file logging + admin error emails in production |
| WhiteNoise | Compresses and serves static files in production without Nginx config per file |
| django-debug-toolbar | Shows SQL queries, cache, and request info in the browser during development |
| Makefile | Shortcuts for common commands so you don't type long commands repeatedly |
project/
├── apps/ Your Django applications go here
│ └── users/ Custom user model (always keep this)
├── config/ Django project package
│ ├── settings/
│ │ ├── base.py Settings shared by all environments
│ │ ├── development.py Local dev: SQLite, console email, debug toolbar
│ │ ├── production.py Production: PostgreSQL, SMTP, HTTPS headers
│ │ └── testing.py Tests: in-memory SQLite, fast password hashing
│ ├── celery.py Celery application setup
│ ├── tasks.py Project-wide Celery tasks (app tasks go in each app)
│ ├── urls.py Root URL config
│ ├── wsgi.py
│ └── asgi.py
├── docker/
│ └── nginx/
│ └── nginx.conf Nginx config for production
├── requirements/
│ ├── base.txt Packages needed in all environments
│ ├── development.txt Dev extras: debug toolbar, pytest, ipython
│ └── production.txt Production extras: psycopg2
├── scripts/
│ └── entrypoint.sh Production Docker entrypoint: waits for DB, migrates, collectstatic
├── static/ Your static files (CSS, JS, images)
├── staticfiles/ Auto-generated by collectstatic — do not edit manually
├── media/ User-uploaded files
├── templates/ HTML templates
│ ├── base.html
│ ├── 404.html
│ └── 500.html
├── logs/ Log files written in production
├── docker-compose.yml Dev stack: Django + Redis + Celery
├── docker-compose.prod.yml Prod stack: adds PostgreSQL + Nginx
├── Dockerfile Multi-stage: development and production targets
├── Makefile Run `make help` to see all commands
├── setup.cfg pytest and flake8 config
├── conftest.py Sets DJANGO_ENV=testing before pytest loads settings
└── .env.example Copy to .env and fill in values
Uses SQLite. No database setup needed.
1. Clone the repo
git clone <your-repo-url>
cd django-starter-pack2. Create and activate a virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# Mac / Linux
source .venv/bin/activate3. Install dependencies
pip install -r requirements/development.txt4. Set up environment variables
cp .env.example .envOpen .env and set SECRET_KEY. Generate one with:
python -c "import secrets; print(secrets.token_hex(50))"5. Create and apply migrations
make setupOr run manually:
python manage.py makemigrations
python manage.py migrate6. Create an admin user
python manage.py createsuperuser7. Start the server
python manage.py runserverOpen http://127.0.0.1:8000/admin/ — log in with the admin account you just created.
Uses Docker with Redis and Celery. Django still uses SQLite inside the container.
1. Copy and edit environment variables
cp .env.example .envSet SECRET_KEY at minimum. Everything else has a default that works out of the box.
2. Start the stack
docker-compose up -dThis starts three containers: web (Django), redis, and celery (worker).
3. Run migrations
make docker-setup4. Create an admin user
make docker-superuser5. Open the app
http://localhost:8000/admin/
python manage.py startapp myapp apps/myappOpen apps/myapp/apps.py and change the name field:
class MyappConfig(AppConfig):
name = 'apps.myapp' # <-- add the apps. prefixRegister it in config/settings/base.py:
LOCAL_APPS = [
'apps.users',
'apps.myapp', # add this
]Open apps/users/models.py and add fields to the User class:
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone = models.CharField(max_length=20, blank=True)
avatar = models.ImageField(upload_to='avatars/', blank=True)Then create and apply the migration:
python manage.py makemigrations
python manage.py migrateApp-specific tasks — create tasks.py inside your app:
# apps/myapp/tasks.py
from celery import shared_task
@shared_task
def send_welcome_email(user_id):
from apps.users.models import User
user = User.objects.get(pk=user_id)
# send email logic hereProject-wide tasks — add them to config/tasks.py.
Call a task from your code:
from apps.myapp.tasks import send_welcome_email
send_welcome_email.delay(user.id) # runs in background via CeleryStart a local worker (if not using Docker):
make workerDevelopment: Everything prints to the terminal. No files are written.
Production:
- WARNING and above go to
logs/app.log(rotates at 10 MB, keeps 5 old files) - Every unhandled 500 error sends a full HTML email to everyone in
DJANGO_ADMINS - All output also goes to stdout so
docker logscaptures it
Using the logger in your code:
import logging
logger = logging.getLogger('apps.myapp') # replace myapp with your app name
logger.info("Order created: %s", order.id)
logger.warning("Low stock for product %s", product.id)
logger.error("Payment failed for user %s", user.id)When a request causes a 500 error in production, Django sends a full report to the people listed in DJANGO_ADMINS. The email has the full stack trace, request headers, POST data, and session contents.
Setup:
- Set
DJANGO_ADMINS=Your Name:your@email.comin.env - Fill in
EMAIL_HOST,EMAIL_HOST_USER,EMAIL_HOST_PASSWORD - Make sure
DJANGO_ENV=production
In development, emails are printed to the terminal — so you can test email flows without an SMTP server.
All variables are in .env.example. Key ones:
| Variable | Required | Description |
|---|---|---|
SECRET_KEY |
Always | Django's signing key. Keep it secret. |
DJANGO_ENV |
Always | development, production, or testing |
ALLOWED_HOSTS |
Production | Comma-separated list of accepted hostnames |
DB_NAME, DB_USER, DB_PASSWORD |
Production | PostgreSQL credentials |
DB_HOST |
Production | Hostname of the database; use db in Docker |
REDIS_URL |
When using Celery | Redis connection URL |
EMAIL_HOST, EMAIL_HOST_USER, etc. |
Production | SMTP server for sending emails |
DJANGO_ADMINS |
Production | Who gets 500 error emails: Name:email@example.com |
SECURE_SSL_REDIRECT |
Production | Set False if your proxy already handles HTTPS |
# Run all tests
pytest
# Run with a coverage report
pytest --cov=apps --cov-report=term-missing
# Run tests in a specific app
pytest apps/users/Tests run with DJANGO_ENV=testing automatically (set in conftest.py), which means:
- SQLite in memory (fast, no cleanup needed)
- Emails go to
django.core.mail.outboxinstead of being sent - MD5 password hashing (faster than bcrypt)
- All logging silenced
1. Prepare environment variables
cp .env.example .envEdit .env with production values:
DJANGO_ENV=productionALLOWED_HOSTS=yourdomain.com,www.yourdomain.com- PostgreSQL and email credentials
DJANGO_ADMINSfor error notifications
2. Start the production stack
docker-compose -f docker-compose.prod.yml up -dThis starts PostgreSQL, Redis, Django (Gunicorn), Celery worker, and Nginx.
The entrypoint script in the web container automatically:
- Waits for PostgreSQL to be ready
- Runs
migrate - Runs
collectstatic
3. Create the first admin user
docker-compose -f docker-compose.prod.yml exec web python manage.py createsuperuser4. Access the app
Nginx listens on port 80. Point your domain's DNS to the server's IP address.
Run make help to list all commands.
make run Start the development server
make shell Open Django interactive shell
make setup Create migrations and apply them (first-time setup)
make migrate Apply existing migrations
make makemigrations Create new migration files
make superuser Create an admin user
make test Run all tests
make lint Check code style with flake8
make worker Start Celery worker locally
make beat Start Celery beat scheduler locally
make docker-up Start dev Docker stack
make docker-down Stop dev Docker stack
make docker-migrate Run migrations in Docker
make docker-superuser Create admin user in Docker
make prod-up Start production Docker stack
make prod-down Stop production Docker stack
make prod-logs Stream production container logs