Deployment¶
How to deploy Django Ninja AIO to production.
ASGI Server¶
Django Ninja AIO is async-first, so you need an ASGI server. Django's built-in runserver is for development only.
Tip
Uvicorn is the most popular ASGI server with excellent performance. Use --workers to match your CPU cores.
ASGI Configuration¶
Make sure your asgi.py is set up correctly:
# myproject/asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
application = get_asgi_application()
Docker¶
A production-ready Dockerfile:
FROM python:3.12-slim
WORKDIR /app
# Install dependencies
COPY pyproject.toml .
RUN pip install --no-cache-dir .
# Copy application code
COPY . .
# Collect static files
RUN python manage.py collectstatic --noinput
# Run with Uvicorn
EXPOSE 8000
CMD ["uvicorn", "myproject.asgi:application", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
With Docker Compose:
# docker-compose.yml
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DJANGO_SETTINGS_MODULE=myproject.settings
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Production Checklist¶
Before deploying, make sure you've addressed these items:
Django settings¶
# settings.py
DEBUG = False
ALLOWED_HOSTS = ["yourdomain.com"]
SECRET_KEY = os.environ["SECRET_KEY"] # Never hardcode!
# Security headers
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
Database¶
Don't use SQLite in production
SQLite is great for development but not suitable for production workloads. Use PostgreSQL for best async Django performance.
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ["DB_NAME"],
"USER": os.environ["DB_USER"],
"PASSWORD": os.environ["DB_PASSWORD"],
"HOST": os.environ["DB_HOST"],
"PORT": os.environ.get("DB_PORT", "5432"),
}
}
Static files¶
Serve static files via a CDN or reverse proxy (Nginx, Caddy), not through Django.
Performance Tips¶
-
Query Optimization
Use
QuerySetconfig on models for automaticselect_related/prefetch_related -
Pagination
Always keep pagination enabled — never return unbounded querysets
-
Database Indexes
Add
db_index=Trueto frequently filtered fields -
ORJSON
Already enabled via
NinjaAIO— fast JSON serialization out of the box
Connection pooling¶
For high-traffic applications, use a connection pooler:
DATABASES = {
"default": {
"ENGINE": "django_pgpool.backends.postgresql",
# ... other settings
"POOL_OPTIONS": {
"max_size": 20,
"min_size": 5,
},
}
}
Reverse Proxy¶
Run behind Nginx or Caddy for TLS termination, static file serving, and load balancing:
upstream django {
server 127.0.0.1:8000;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location /static/ {
alias /app/staticfiles/;
}
location / {
proxy_pass http://django;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
See Also¶
-
Performance Benchmarks
See how Django Ninja AIO performs under load
-
ORJSON Renderer
Configure JSON serialization options
-
Troubleshooting
Common issues and solutions