Deployment¶
This section covers key considerations for deploying Django Cast in production.
Prerequisites¶
Python 3.11+
A database (PostgreSQL or SQLite)
A reverse proxy (e.g., Traefik, Nginx) with a WSGI server (e.g., Gunicorn)
Basic Configuration¶
Your production settings should include:
DEBUG = False
ALLOWED_HOSTS = ["your-domain.com"]
SECRET_KEY = os.environ["SECRET_KEY"] # never hardcode
# Wagtail
WAGTAILADMIN_BASE_URL = "https://your-domain.com"
See Installation for the full INSTALLED_APPS, MIDDLEWARE,
and URL configuration.
Keep dev-only routes disabled in production unless you explicitly need them:
CAST_ENABLE_DEV_TOOLS = False
Application Server¶
A typical production setup uses Gunicorn behind a reverse proxy:
gunicorn --workers 4 --timeout 600 --bind 127.0.0.1:8000 config.wsgi:application
Manage the process with systemd for automatic restarts and logging.
Transcript Worker¶
If the site enables Voxhelm transcript generation from Wagtail admin, run a
Django Tasks database worker in addition to the web process. Install the
optional transcript-worker extra first; it requires a Wagtail/django-tasks
combination compatible with django-tasks-db 0.12. Wagtail 7.0 LTS uses
django-tasks 0.7 and is not compatible with that database backend.
uv pip install "django-cast[transcript-worker]"
python manage.py db_worker --backend cast_transcripts --worker-id homepage-transcripts
Use a distinct --worker-id per deployed site, for example
python-podcast-transcripts for a second site sharing the same codebase.
The default task backend should remain immediate; only the
cast_transcripts backend should point at django_tasks_db.DatabaseBackend.
The web process and transcript worker must both receive the Voxhelm
configuration used for job submission and artifact downloads. For
deployment-managed secrets, set CAST_VOXHELM_API_BASE and
CAST_VOXHELM_API_KEY in the shared process environment; the Wagtail
Voxhelm settings token field can stay blank in that setup. If a site-level
Wagtail value is set, it takes precedence for that site.
If CAST_VOXHELM_DIARIZATION_ENABLED is enabled, make sure the Voxhelm
backend has diarization support configured. Full-episode diarization can be
slow and CPU-heavy, so keep it on the queued transcript worker path instead of
waiting for completion in a Wagtail admin request.
Static Files¶
Django Cast ships pre-built JavaScript assets (image gallery, Podlove audio player). Collect all static files before deployment:
python manage.py collectstatic --noinput
Serve the STATIC_ROOT directory via your reverse proxy, a storage backend,
or a CDN.
Media Storage¶
Uploaded media (images, audio, video) is stored via Django’s
STORAGES["default"] backend. A common production setup uses an object
store like AWS S3 with CloudFront as CDN.
See Using a CDN (AWS S3 + Cloudfront) in the Settings reference for S3 + CloudFront configuration details.
Important
Set DELETE_WAGTAIL_IMAGES = False when using S3. This prevents
your development environment from accidentally deleting production images.
If you use automatic media processing features in production, make sure the required FFmpeg tools are installed on your application hosts:
ffprobefor audio duration extraction, chapter-mark import, and video dimension detectionffmpegfor video poster generation
For backup and restore of media files, see Backup and the media management commands.
Database¶
Run migrations before starting the application:
python manage.py migrate
Both PostgreSQL and SQLite are supported. PostgreSQL is the more typical production choice, especially for multi-server deployments. SQLite can work for simpler single-server setups, but operational characteristics such as locking, backups, and write concurrency remain your responsibility.
Image Renditions¶
After initial deployment or after changing image slot dimension settings, generate image renditions:
python manage.py sync_renditions
This creates responsive image variants used by the gallery and post templates. See Management Commands for details.
Example: Ansible-Based Deployment¶
A production deployment typically involves:
Sync source code to the server (rsync or git clone)
Create/update a virtualenv and install dependencies (
uv sync --frozen)Set environment variables (
SECRET_KEY,DATABASE_URL, AWS credentials, etc.) via your deployment environment or an.envfileRun
python manage.py migrateRun
python manage.py collectstatic --noinputRun
python manage.py update_index(Wagtail search index)Restart the application service (e.g.,
systemctl restart mysite)
TLS certificates can be managed automatically via Let’s Encrypt with a reverse proxy like Traefik.
Checklist¶
[ ]
DEBUG = False[ ]
SECRET_KEYset from environment variable[ ]
ALLOWED_HOSTSconfigured[ ]
WAGTAILADMIN_BASE_URLset to production domain[ ]
CAST_ENABLE_DEV_TOOLS = Falseunless explicitly required[ ] Database configured and migrations applied
[ ]
collectstaticrun[ ] Media storage configured (local filesystem or S3)
[ ]
DELETE_WAGTAIL_IMAGES = Falseif using S3[ ]
ffprobe/ffmpeginstalled if using audio/video processing features[ ] Image renditions generated with
sync_renditions[ ] Reverse proxy with TLS configured
[ ] Application server (Gunicorn) managed by systemd