Deploying Django LiveView requires an ASGI server (like Daphne or Uvicorn), Redis for the channel layer, and proper WebSocket support.
Production Requirements
ASGI Server: Daphne, Uvicorn, or Hypercorn
Redis: For channel layer (shared state between workers)
WebSocket Support: Reverse proxy must support WebSockets (Nginx, Caddy, Traefik)
Process Manager: Supervisor, systemd, or Docker
SSL/TLS: Required for
wss://connections in production
Using Daphne (Recommended)
Install Daphne:
pip install daphne
Run Daphne in production:
daphne -b 0.0.0.0 -p 8000 myproject.asgi:application
With multiple workers for better performance:
daphne -b 0.0.0.0 -p 8000 --workers 4 myproject.asgi:application
Using Uvicorn
Install Uvicorn:
pip install uvicorn[standard]
Run Uvicorn:
uvicorn myproject.asgi:application --host 0.0.0.0 --port 8000 --workers 4
Redis Configuration for Production
Update settings.py for production Redis:
# settings.py
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [
{
"address": ("redis", 6379), # Redis hostname
"password": "your-redis-password",
"db": 0,
}
],
"capacity": 1500, # Max messages per channel
"expiry": 10, # Message expiry in seconds
},
},
}
For Redis Sentinel (high availability):
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [
{
"sentinels": [
("sentinel1", 26379),
("sentinel2", 26379),
("sentinel3", 26379),
],
"master_name": "mymaster",
"password": "your-redis-password",
}
],
},
},
}
Nginx Configuration
Configure Nginx to proxy WebSocket connections:
upstream django {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name example.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Static files
location /static/ {
alias /path/to/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /path/to/media/;
expires 7d;
}
# WebSocket support
location /ws/ {
proxy_pass http://django;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
# Increase timeout for long-lived connections
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
# Regular HTTP requests
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;
}
}
Docker Deployment
Dockerfile:
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy project
COPY . .
# Collect static files
RUN python manage.py collectstatic --noinput
# Expose port
EXPOSE 8000
# Run Daphne
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "myproject.asgi:application"]
docker-compose.yml:
version: '3.8'
services:
redis:
image: redis:7-alpine
restart: always
volumes:
- redis_data:/data
command: redis-server --requirepass your-redis-password
web:
build: .
restart: always
ports:
- "8000:8000"
depends_on:
- redis
environment:
- REDIS_HOST=redis
- REDIS_PASSWORD=your-redis-password
- DJANGO_SETTINGS_MODULE=myproject.settings
volumes:
- static_volume:/app/staticfiles
- media_volume:/app/media
nginx:
image: nginx:alpine
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- static_volume:/static:ro
- media_volume:/media:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- web
volumes:
redis_data:
static_volume:
media_volume:
Systemd Service
Create /etc/systemd/system/django-liveview.service:
[Unit]
Description=Django LiveView Application
After=network.target redis.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/path/to/project
Environment="PATH=/path/to/venv/bin"
ExecStart=/path/to/venv/bin/daphne -b 0.0.0.0 -p 8000 myproject.asgi:application
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable django-liveview
sudo systemctl start django-liveview
sudo systemctl status django-liveview
Environment Variables
Store sensitive configuration in environment variables:
# settings.py
import os
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY")
DEBUG = os.environ.get("DJANGO_DEBUG", "False") == "True"
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",")
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [{
"address": (
os.environ.get("REDIS_HOST", "127.0.0.1"),
int(os.environ.get("REDIS_PORT", 6379))
),
"password": os.environ.get("REDIS_PASSWORD"),
}],
},
},
}
Performance Tuning
Use Redis persistence (
appendonly yes) for channel layer reliabilityIncrease worker count based on CPU cores (
workers = CPU cores * 2 + 1)Set proper
capacityandexpiryin channel layer configEnable HTTP/2 in Nginx for better performance
Use connection pooling for database
Configure WebSocket timeouts appropriately
Monitor Redis memory usage and set
maxmemorylimits
Monitoring
Monitor your Django LiveView application:
# settings.py
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"file": {
"level": "INFO",
"class": "logging.FileHandler",
"filename": "/var/log/django/liveview.log",
},
},
"loggers": {
"liveview": {
"handlers": ["file"],
"level": "INFO",
"propagate": False,
},
},
}
Monitor key metrics:
WebSocket connection count
Redis memory usage
Handler execution time
Error rates
Message throughput
Security Checklist
✓ Use HTTPS/WSS in production
✓ Set
ALLOWED_HOSTScorrectly✓ Use
AllowedHostsOriginValidatorin ASGI✓ Enable Redis password authentication
✓ Set proper CORS headers if needed
✓ Use authentication middleware for protected handlers
✓ Validate and sanitize all user input
✓ Set WebSocket rate limiting
✓ Monitor for suspicious activity
Scaling Horizontally
To scale beyond one server:
Use external Redis (not Redis on the same server)
Share sessions across servers (database or Redis sessions)
Load balance WebSocket connections (sticky sessions not required)
Use Redis Sentinel or Cluster for Redis high availability
Monitor all instances with centralized logging