A production-ready Django REST Framework + WebSockets project using Django Channels and Redis
Learn how to deploy a real-time Django application with WebSocket support!
- π Overview
- β¨ Features
- π οΈ Tech Stack
- π» Quick Start
- π§ͺ Testing WebSockets
- π§ Project Structure
- βοΈ Configuration
- π Deployment Guide
- π‘ How It Works
- π Troubleshooting
- π€ Contributing
This project is a learning-focused implementation of Django REST Framework with real-time WebSocket capabilities using Django Channels and Redis as the channel layer backend.
Perfect for:
- Learning Django Channels & WebSocket implementation
- Understanding ASGI vs WSGI deployment
- Hosting real-time applications in production
- Building chat apps, live notifications, real-time dashboards
- β‘ REST API - Django REST Framework endpoints
- π£οΈ WebSocket Support - Real-time bi-directional communication
- π¬ Echo Chat Consumer - Simple message echoing demo
- π Broadcast Notifications - Group-based message broadcasting
- π Redis Channel Layer - Scalable message passing between consumers
- π³ Docker Ready - Complete Docker Compose setup
- π― Production Ready - Environment-based configuration
- π¦ Easy Deployment - Multiple hosting options covered
| Component | Technology |
|---|---|
| Web Framework | Django 4.2 |
| API | Django REST Framework 3.14 |
| WebSockets | Django Channels 4.0 |
| Channel Layer | Redis 5.x + channels-redis |
| ASGI Server | Daphne 4.0 |
| Database | SQLite (dev) / PostgreSQL (prod) |
| Python | 3.11+ |
# Clone repository
git clone https://github.com/vrajvithalani/demo-django-hosting.git
cd demo-django-hosting
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt# Copy environment file
cp .env.example .env
# Edit .env if needed (defaults work for local development)Option A: Using Docker (Recommended)
docker run -d -p 6379:6379 redis:7-alpineOption B: Local Installation
# macOS
brew install redis
brew services start redis
# Ubuntu/Debian
sudo apt update
sudo apt install redis-server
sudo systemctl start redis
# Verify Redis is running
redis-cli ping # Should return "PONG"# Apply database migrations
python manage.py migrate
# Start Daphne (ASGI server)
daphne -b 0.0.0.0 -p 8000 config.asgi:application- API Health Check: http://localhost:8000/api/health/
- WebSocket Test Page: http://localhost:8000/api/ws-test/
- Admin Panel: http://localhost:8000/admin/ (create superuser first)
Easiest way to run everything!
# Build and start all services (Django + Redis)
docker-compose up --build
# Access application at http://localhost:8000Stop services:
docker-compose down- Start the server (see Quick Start above)
- Open browser: http://localhost:8000/api/ws-test/
- Click "Connect" button
- Type a message and click "Send"
- Watch the echo response appear!
Open your browser's JavaScript console and run:
// Connect to echo chat
const socket = new WebSocket('ws://localhost:8000/ws/chat/');
socket.onopen = () => console.log('Connected!');
socket.onmessage = (e) => console.log('Received:', JSON.parse(e.data));
// Send a message
socket.send(JSON.stringify({ message: 'Hello WebSocket!' }));import asyncio
import websockets
import json
async def test_websocket():
uri = "ws://localhost:8000/ws/chat/"
async with websockets.connect(uri) as websocket:
# Receive welcome message
response = await websocket.recv()
print(f"Connected: {response}")
# Send test message
await websocket.send(json.dumps({"message": "Hello from Python!"}))
# Receive echo
response = await websocket.recv()
print(f"Echo: {response}")
asyncio.run(test_websocket())| Endpoint | Purpose |
|---|---|
ws://localhost:8000/ws/chat/ |
Echo chat - messages echoed back to sender |
ws://localhost:8000/ws/notifications/ |
Broadcast - messages sent to all connected clients |
demo-django-hosting/
βββ config/ # Django project settings
β βββ __init__.py
β βββ settings.py # Main settings (Channels, Redis, DRF)
β βββ asgi.py # ASGI config with WebSocket routing
β βββ urls.py # URL configuration
β βββ wsgi.py # WSGI config (not used with Channels)
βββ chat/ # WebSocket app
β βββ consumers.py # WebSocket consumers (ChatConsumer, NotificationConsumer)
β βββ routing.py # WebSocket URL routing
β βββ views.py # DRF API views
β βββ urls.py # HTTP URL patterns
βββ requirements.txt # Python dependencies
βββ .env.example # Environment variables template
βββ Dockerfile # Docker image definition
βββ docker-compose.yml # Multi-container setup (Django + Redis)
βββ manage.py # Django management script
βββ README.md # This file
Edit .env file:
# Django
SECRET_KEY=your-secret-key-change-in-production
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1,yourdomain.com
# Redis (Channel Layer)
REDIS_HOST=localhost # Use 'redis' for Docker
REDIS_PORT=6379config/settings.py:
# Must be at the top of INSTALLED_APPS
INSTALLED_APPS = [
'daphne', # ASGI server
'django.contrib.admin',
# ... other apps
'channels',
'rest_framework',
'chat',
]
# ASGI application (replaces WSGI for Channels)
ASGI_APPLICATION = 'config.asgi.application'
# Redis as channel layer backend
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [("localhost", 6379)],
},
},
}- Redis server (managed or self-hosted)
- PostgreSQL database (recommended for production)
- ASGI-compatible server (Daphne, Uvicorn)
Perfect for: Learning server administration, full control
# Update system
sudo apt update && sudo apt upgrade -y
# Install Python & dependencies
sudo apt install python3-pip python3-venv nginx redis-server postgresql postgresql-contrib -y
# Start Redis
sudo systemctl start redis
sudo systemctl enable redis# Clone repository
git clone https://github.com/vrajvithalani/demo-django-hosting.git
cd demo-django-hosting
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
nano .env # Edit with production values# Create database
sudo -u postgres psql
CREATE DATABASE django_channels_db;
CREATE USER django_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE django_channels_db TO django_user;
\q
# Update settings.py to use PostgreSQLpython manage.py migrate
python manage.py collectstatic --noinput
python manage.py createsuperuserCreate /etc/systemd/system/daphne.service:
[Unit]
Description=Daphne ASGI Server for Django Channels
After=network.target redis.service
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/demo-django-hosting
Environment="PATH=/path/to/venv/bin"
ExecStart=/path/to/venv/bin/daphne -b 0.0.0.0 -p 8000 config.asgi:application
[Install]
WantedBy=multi-user.target# Enable and start service
sudo systemctl daemon-reload
sudo systemctl start daphne
sudo systemctl enable daphne
sudo systemctl status daphneCreate /etc/nginx/sites-available/django-channels:
server {
listen 80;
server_name yourdomain.com;
# HTTP requests
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# WebSocket requests
location /ws/ {
proxy_pass http://127.0.0.1:8000;
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;
}
# Static files
location /static/ {
alias /path/to/demo-django-hosting/staticfiles/;
}
}# Enable site
sudo ln -s /etc/nginx/sites-available/django-channels /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxsudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.comUpdate WebSocket URL to wss:// in production!
Perfect for: Quick deployment, managed Redis
-
Create Railway Account: https://railway.app
-
Install Railway CLI:
npm install -g @railway/cli railway login
-
Initialize Project:
railway init railway link
-
Add Redis Service:
- Dashboard β New β Database β Redis
- Copy connection URL
-
Set Environment Variables:
railway variables set SECRET_KEY="your-secret-key" railway variables set DEBUG="False" railway variables set ALLOWED_HOSTS="your-app.railway.app" railway variables set REDIS_HOST="redis.railway.internal"
-
Create Procfile:
web: daphne -b 0.0.0.0 -p $PORT config.asgi:application -
Deploy:
railway up
Update WebSocket URLs to use your Railway domain!
Perfect for: Enterprise applications, AWS ecosystem
-
Install EB CLI:
pip install awsebcli
-
Initialize EB:
eb init -p python-3.11 django-channels-app
-
Create Environment:
eb create django-channels-env
-
Configure Redis: Use AWS ElastiCache for Redis
-
Set Environment Variables in EB Console
-
Deploy:
eb deploy
- WSGI (Traditional Django): Synchronous, HTTP only
- ASGI (Django Channels): Asynchronous, supports WebSockets, HTTP/2
Client (Browser)
β HTTP Request
β WebSocket Connection
Nginx (Reverse Proxy)
β
Daphne (ASGI Server)
β
Django Channels
ββ HTTP β Django Views (REST API)
ββ WebSocket β Consumers
β
Redis (Channel Layer)
β
Inter-consumer communication
- Client connects to
ws://domain.com/ws/chat/ - Nginx forwards to Daphne (upgrades to WebSocket)
- Daphne routes to
ChatConsumerviarouting.py - Consumer accepts connection
- Messages exchanged via
receive()andsend() - Redis enables multi-server broadcasting
# Check Redis is running
redis-cli ping
# Check connection
redis-cli -h localhost -p 6379 ping
# Restart Redis
sudo systemctl restart redis- Check
ALLOWED_HOSTSin settings.py - Verify CORS settings if connecting from different domain
- Check Nginx WebSocket configuration
- Verify Redis is accessible from Django
- Check
CHANNEL_LAYERSconfiguration - Review Daphne logs:
journalctl -u daphne -f
pip install -r requirements.txt# Kill process on port 8000
sudo lsof -t -i:8000 | xargs kill -9
# Or use different port
daphne -b 0.0.0.0 -p 8080 config.asgi:applicationContributions welcome! Please:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
MIT License - feel free to use for learning and production!
Built for learning Django Channels & WebSocket deployment
Made with β€οΈ by Vraj Vithalani