Environment Variables Reference
Complete reference for all environment variables used in ThrillWiki.
Quick Start
- Copy the example file:
cp .env.example .env
- Edit
.env with your values
- Run validation:
python manage.py validate_settings
Required Variables
These must be set in all environments.
| Variable |
Type |
Description |
SECRET_KEY |
string |
Django secret key (minimum 50 characters) |
DATABASE_URL |
url |
Database connection URL |
Production-Required Variables
These variables must be explicitly set for production deployments. The application will not function correctly in production without them.
Important: See .env.example for example values and PRODUCTION_CHECKLIST.md for deployment verification steps.
| Variable |
Type |
Format/Example |
Description |
DEBUG |
bool |
False |
Must be False in production. Enables detailed error pages and debug toolbar when True. |
DJANGO_SETTINGS_MODULE |
string |
config.django.production |
Must use config.django.production for production. Controls which settings module Django loads. |
ALLOWED_HOSTS |
list |
thrillwiki.com,www.thrillwiki.com |
Required. Comma-separated list of valid hostnames. No default in production - requests will fail without this. |
CSRF_TRUSTED_ORIGINS |
list |
https://thrillwiki.com,https://www.thrillwiki.com |
Required. Must include https:// prefix. CSRF validation fails without proper configuration. |
REDIS_URL |
url |
redis://[:password@]host:6379/0 |
Required for caching and sessions. Production uses Redis for caching, session storage, and Celery broker. |
Production Settings Behavior
When DJANGO_SETTINGS_MODULE=config.django.production:
DEBUG is always False
ALLOWED_HOSTS has no default - must be explicitly set
CSRF_TRUSTED_ORIGINS has no default - must be explicitly set
- SSL redirect is enforced (
SECURE_SSL_REDIRECT=True)
- Secure cookies are enforced (
SESSION_COOKIE_SECURE=True, CSRF_COOKIE_SECURE=True)
- HSTS is enabled with 1-year max-age
- Redis cache is required (application will fail if
REDIS_URL is not set)
Validation
Run the following to validate your production configuration:
Core Django Settings
| Variable |
Type |
Default |
Description |
DEBUG |
bool |
True |
Enable debug mode |
DJANGO_SETTINGS_MODULE |
string |
config.django.local |
Settings module to use |
ALLOWED_HOSTS |
list |
localhost,127.0.0.1 |
Comma-separated allowed hosts |
CSRF_TRUSTED_ORIGINS |
list |
`` |
Comma-separated trusted origins |
Database Configuration
| Variable |
Type |
Default |
Description |
DATABASE_URL |
url |
(required) |
Database connection URL |
DATABASE_CONN_MAX_AGE |
int |
600 |
Connection pool timeout (seconds) |
DATABASE_CONNECT_TIMEOUT |
int |
10 |
Connection timeout (seconds) |
DATABASE_STATEMENT_TIMEOUT |
int |
30000 |
Query timeout (milliseconds) |
DATABASE_READ_REPLICA_URL |
url |
`` |
Optional read replica URL |
Database URL Formats
GeoDjango Settings
| Variable |
Type |
Default |
Description |
GDAL_LIBRARY_PATH |
path |
/opt/homebrew/lib/libgdal.dylib |
Path to GDAL library |
GEOS_LIBRARY_PATH |
path |
/opt/homebrew/lib/libgeos_c.dylib |
Path to GEOS library |
Platform-Specific Paths
Cache Configuration
| Variable |
Type |
Default |
Description |
REDIS_URL |
url |
redis://127.0.0.1:6379/1 |
Redis connection URL |
REDIS_SESSIONS_URL |
url |
(from REDIS_URL) |
Redis URL for sessions |
REDIS_API_URL |
url |
(from REDIS_URL) |
Redis URL for API cache |
REDIS_MAX_CONNECTIONS |
int |
100 |
Maximum Redis connections |
REDIS_CONNECTION_TIMEOUT |
int |
20 |
Redis connection timeout |
REDIS_IGNORE_EXCEPTIONS |
bool |
True |
Graceful degradation |
CACHE_MIDDLEWARE_SECONDS |
int |
300 |
Cache middleware timeout |
CACHE_MIDDLEWARE_KEY_PREFIX |
string |
thrillwiki |
Cache key prefix |
CACHE_KEY_PREFIX |
string |
thrillwiki |
Default cache key prefix |
Email Configuration
| Variable |
Type |
Default |
Description |
EMAIL_BACKEND |
string |
django_forwardemail.backends.ForwardEmailBackend |
Email backend class |
SERVER_EMAIL |
email |
django_webmaster@thrillwiki.com |
Server email address |
DEFAULT_FROM_EMAIL |
string |
ThrillWiki <noreply@thrillwiki.com> |
Default from address |
EMAIL_SUBJECT_PREFIX |
string |
[ThrillWiki] |
Subject prefix |
EMAIL_TIMEOUT |
int |
30 |
Email operation timeout |
ForwardEmail Settings
| Variable |
Type |
Default |
Description |
FORWARD_EMAIL_BASE_URL |
url |
https://api.forwardemail.net |
API base URL |
FORWARD_EMAIL_API_KEY |
string |
`` |
API key |
FORWARD_EMAIL_DOMAIN |
string |
`` |
Sending domain |
SMTP Settings
| Variable |
Type |
Default |
Description |
EMAIL_HOST |
string |
localhost |
SMTP server |
EMAIL_PORT |
int |
587 |
SMTP port |
EMAIL_USE_TLS |
bool |
True |
Use TLS |
EMAIL_USE_SSL |
bool |
False |
Use SSL |
EMAIL_HOST_USER |
string |
`` |
SMTP username |
EMAIL_HOST_PASSWORD |
string |
`` |
SMTP password |
Security Settings
SSL/HTTPS
| Variable |
Type |
Default |
Description |
SECURE_SSL_REDIRECT |
bool |
False |
Redirect HTTP to HTTPS |
SECURE_PROXY_SSL_HEADER |
tuple |
`` |
Proxy SSL header |
HSTS (HTTP Strict Transport Security)
| Variable |
Type |
Default |
Description |
SECURE_HSTS_SECONDS |
int |
31536000 |
HSTS max-age |
SECURE_HSTS_INCLUDE_SUBDOMAINS |
bool |
True |
Include subdomains |
SECURE_HSTS_PRELOAD |
bool |
False |
Allow preload |
SECURE_REDIRECT_EXEMPT |
list |
`` |
URLs exempt from redirect |
| Variable |
Type |
Default |
Description |
SECURE_BROWSER_XSS_FILTER |
bool |
True |
XSS filter header |
SECURE_CONTENT_TYPE_NOSNIFF |
bool |
True |
Nosniff header |
X_FRAME_OPTIONS |
string |
DENY |
Frame options |
SECURE_REFERRER_POLICY |
string |
strict-origin-when-cross-origin |
Referrer policy |
SECURE_CROSS_ORIGIN_OPENER_POLICY |
string |
same-origin |
COOP header |
Cookie Security
| Variable |
Type |
Default |
Description |
SESSION_COOKIE_SECURE |
bool |
False |
HTTPS-only session cookie |
SESSION_COOKIE_HTTPONLY |
bool |
True |
No JS access |
SESSION_COOKIE_SAMESITE |
string |
Lax |
SameSite attribute |
SESSION_COOKIE_AGE |
int |
3600 |
Cookie age (seconds) |
CSRF_COOKIE_SECURE |
bool |
False |
HTTPS-only CSRF cookie |
CSRF_COOKIE_HTTPONLY |
bool |
True |
No JS access |
CSRF_COOKIE_SAMESITE |
string |
Lax |
SameSite attribute |
Cloudflare Turnstile
| Variable |
Type |
Default |
Description |
TURNSTILE_SITE_KEY |
string |
`` |
Turnstile site key |
TURNSTILE_SECRET_KEY |
string |
`` |
Turnstile secret key |
TURNSTILE_VERIFY_URL |
url |
https://challenges.cloudflare.com/turnstile/v0/siteverify |
Verification URL |
API Configuration
CORS
| Variable |
Type |
Default |
Description |
CORS_ALLOWED_ORIGINS |
list |
`` |
Allowed origins |
CORS_ALLOW_ALL_ORIGINS |
bool |
False |
Allow all origins |
Rate Limiting
| Variable |
Type |
Default |
Description |
API_RATE_LIMIT_PER_MINUTE |
int |
60 |
Requests per minute |
API_RATE_LIMIT_PER_HOUR |
int |
1000 |
Requests per hour |
API_RATE_LIMIT_ANON_PER_MINUTE |
int |
60 |
Anonymous rate limit |
API_RATE_LIMIT_USER_PER_HOUR |
int |
1000 |
Authenticated rate limit |
| Variable |
Type |
Default |
Description |
API_PAGE_SIZE |
int |
20 |
Default page size |
API_MAX_PAGE_SIZE |
int |
100 |
Maximum page size |
API_VERSION |
string |
1.0.0 |
API version string |
JWT Configuration
| Variable |
Type |
Default |
Description |
JWT_ACCESS_TOKEN_LIFETIME_MINUTES |
int |
15 |
Access token lifetime |
JWT_REFRESH_TOKEN_LIFETIME_DAYS |
int |
7 |
Refresh token lifetime |
JWT_ISSUER |
string |
thrillwiki |
Token issuer |
Cloudflare Images
| Variable |
Type |
Default |
Description |
CLOUDFLARE_IMAGES_ACCOUNT_ID |
string |
`` |
Account ID |
CLOUDFLARE_IMAGES_API_TOKEN |
string |
`` |
API token |
CLOUDFLARE_IMAGES_ACCOUNT_HASH |
string |
`` |
Account hash |
CLOUDFLARE_IMAGES_WEBHOOK_SECRET |
string |
`` |
Webhook secret |
CLOUDFLARE_IMAGES_DEFAULT_VARIANT |
string |
public |
Default variant |
CLOUDFLARE_IMAGES_UPLOAD_TIMEOUT |
int |
300 |
Upload timeout |
CLOUDFLARE_IMAGES_CLEANUP_HOURS |
int |
24 |
Cleanup interval |
CLOUDFLARE_IMAGES_MAX_FILE_SIZE |
int |
10485760 |
Max file size (bytes) |
CLOUDFLARE_IMAGES_REQUIRE_SIGNED_URLS |
bool |
False |
Require signed URLs |
Road Trip Service
| Variable |
Type |
Default |
Description |
ROADTRIP_USER_AGENT |
string |
ThrillWiki/1.0 |
OSM API user agent |
ROADTRIP_CACHE_TIMEOUT |
int |
86400 |
Geocoding cache timeout |
ROADTRIP_ROUTE_CACHE_TIMEOUT |
int |
21600 |
Route cache timeout |
ROADTRIP_MAX_REQUESTS_PER_SECOND |
int |
1 |
Rate limit |
ROADTRIP_REQUEST_TIMEOUT |
int |
10 |
Request timeout |
ROADTRIP_MAX_RETRIES |
int |
3 |
Max retries |
ROADTRIP_BACKOFF_FACTOR |
int |
2 |
Retry backoff |
Logging Configuration
| Variable |
Type |
Default |
Description |
LOG_DIR |
path |
logs |
Log directory |
ROOT_LOG_LEVEL |
string |
INFO |
Root log level |
DJANGO_LOG_LEVEL |
string |
WARNING |
Django log level |
DB_LOG_LEVEL |
string |
WARNING |
Database log level |
APP_LOG_LEVEL |
string |
INFO |
Application log level |
PERFORMANCE_LOG_LEVEL |
string |
INFO |
Performance log level |
QUERY_LOG_LEVEL |
string |
WARNING |
Query log level |
NPLUSONE_LOG_LEVEL |
string |
WARNING |
N+1 detection level |
REQUEST_LOG_LEVEL |
string |
INFO |
Request log level |
CELERY_LOG_LEVEL |
string |
INFO |
Celery log level |
CONSOLE_LOG_LEVEL |
string |
INFO |
Console output level |
FILE_LOG_LEVEL |
string |
INFO |
File output level |
FILE_LOG_FORMATTER |
string |
json |
File log format |
Monitoring
Sentry
| Variable |
Type |
Default |
Description |
SENTRY_DSN |
url |
`` |
Sentry DSN |
SENTRY_ENVIRONMENT |
string |
production |
Sentry environment |
SENTRY_TRACES_SAMPLE_RATE |
float |
0.1 |
Trace sampling rate |
Health Checks
| Variable |
Type |
Default |
Description |
HEALTH_CHECK_DISK_USAGE_MAX |
int |
90 |
Max disk usage % |
HEALTH_CHECK_MEMORY_MIN |
int |
100 |
Min available memory MB |
Feature Flags
| Variable |
Type |
Default |
Description |
ENABLE_DEBUG_TOOLBAR |
bool |
True |
Enable debug toolbar |
ENABLE_SILK_PROFILER |
bool |
False |
Enable Silk profiler |
TEMPLATES_ENABLED |
bool |
True |
Enable Django templates |
AUTOCOMPLETE_BLOCK_UNAUTHENTICATED |
bool |
False |
Require auth for autocomplete |
File Upload Settings
| Variable |
Type |
Default |
Description |
FILE_UPLOAD_MAX_MEMORY_SIZE |
int |
2621440 |
Max in-memory upload (bytes) |
DATA_UPLOAD_MAX_MEMORY_SIZE |
int |
10485760 |
Max request size (bytes) |
DATA_UPLOAD_MAX_NUMBER_FIELDS |
int |
1000 |
Max form fields |
WhiteNoise Settings
| Variable |
Type |
Default |
Description |
WHITENOISE_COMPRESSION_QUALITY |
int |
90 |
Compression quality |
WHITENOISE_MAX_AGE |
int |
31536000 |
Cache max-age |
WHITENOISE_MANIFEST_STRICT |
bool |
False |
Strict manifest mode |
Secret Management
| Variable |
Type |
Default |
Description |
SECRET_ROTATION_ENABLED |
bool |
False |
Enable rotation checks |
SECRET_KEY_VERSION |
string |
1 |
Current secret version |
SECRET_EXPIRY_WARNING_DAYS |
int |
30 |
Warning threshold |
PASSWORD_MIN_LENGTH |
int |
8 |
Minimum password length |
Celery Configuration
| Variable |
Type |
Default |
Description |
CELERY_TASK_ALWAYS_EAGER |
bool |
False |
Run tasks synchronously |
CELERY_TASK_EAGER_PROPAGATES |
bool |
False |
Propagate task errors |
Third-Party Integrations
| Variable |
Type |
Default |
Description |
FRONTEND_DOMAIN |
url |
https://thrillwiki.com |
Frontend URL |
LOGIN_REDIRECT_URL |
path |
/ |
Post-login redirect |
ACCOUNT_LOGOUT_REDIRECT_URL |
path |
/ |
Post-logout redirect |
ACCOUNT_EMAIL_VERIFICATION |
string |
mandatory |
Email verification mode |