Production Settings
Security, storage, caching, and email configuration for production.
Security
SSL & HTTPS
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = TrueCookies
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_NAME = "__Secure-sessionid"
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_NAME = "__Secure-csrftoken"
CSRF_COOKIE_HTTPONLY = TrueHSTS
SECURE_HSTS_SECONDS = 60 # Increase to 518400 after verifying
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = TrueOther
X_FRAME_OPTIONS = "DENY"Password Hashing
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher", # Primary
"django.contrib.auth.hashers.PBKDF2PasswordHasher", # Fallback
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
]CORS
CORS_URLS_REGEX = r"^/api/.*$" # Only API routes
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:3000",
"https://www.yourdomain.com",
"https://yourdomain.com",
]Add your frontend domain to CORS_ALLOWED_ORIGINS in settings.
AWS / S3 Storage
Configuration
AWS_ACCESS_KEY_ID = env("DJANGO_AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = env("DJANGO_AWS_SECRET_ACCESS_KEY")
AWS_STORAGE_BUCKET_NAME = env("DJANGO_AWS_STORAGE_BUCKET_NAME")
AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None)
AWS_S3_CUSTOM_DOMAIN = env("DJANGO_AWS_S3_CUSTOM_DOMAIN", default=None)
AWS_QUERYSTRING_AUTH = False
AWS_S3_MAX_MEMORY_SIZE = 100 * 1024 * 1024 # 100MBStorage Backends
STORAGES = {
"default": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {"location": "media"},
},
"staticfiles": {
"BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": {"location": "static"},
},
}Static files and media are stored on S3. collectstatic uploads to the static/ prefix; media uploads go to media/. Document files use the separate presigned URL flow with the documents/ prefix.
Caching Headers
AWS_S3_OBJECT_PARAMETERS = {
"CacheControl": f"max-age={60*60*24*7}, s-maxage={60*60*24*7}, must-revalidate"
}Objects are cached for 7 days. Use a CloudFront distribution (AWS_S3_CUSTOM_DOMAIN) for global CDN.
Caching
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": REDIS_URL,
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"IGNORE_EXCEPTIONS": True,
},
}
}Redis is used for both Celery broker and Django cache. IGNORE_EXCEPTIONS = True ensures the application doesn't crash if Redis is temporarily unavailable.
Resend (Default)
EMAIL_BACKEND = "anymail.backends.resend.EmailBackend"
RESEND_API_KEY = env("RESEND_API_KEY")
DEFAULT_FROM_EMAIL = env("DJANGO_DEFAULT_FROM_EMAIL", default="support@yourdomain.com")Alternative Providers
HyperSaaS supports multiple email backends via django-anymail:
| Provider | Backend |
|---|---|
| Resend | anymail.backends.resend.EmailBackend |
| Amazon SES | anymail.backends.amazon_ses.EmailBackend |
| SendGrid | anymail.backends.sendgrid.EmailBackend |
| Console (dev) | django.core.mail.backends.console.EmailBackend |
Celery
Production Worker
celery -A config.celery_app worker -l INFOConfiguration
CELERY_BROKER_URL = REDIS_URL
CELERY_RESULT_BACKEND = REDIS_URL
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
CELERY_TASK_TIME_LIMIT = 5 * 60 # 5 minutes
CELERY_TASK_SOFT_TIME_LIMIT = 60 # 1 minute
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_WORKER_SEND_TASK_EVENTS = TrueBeat Scheduler
Celery Beat uses DatabaseScheduler — periodic tasks are stored in the database and manageable via Django Admin.
Flower
Flower provides real-time Celery monitoring:
CELERY_FLOWER_USER = env("CELERY_FLOWER_USER")
CELERY_FLOWER_PASSWORD = env("CELERY_FLOWER_PASSWORD")Protected with basic auth in production. Accessible on port 5555 via Traefik.
Environment Variables
Required
| Variable | Description |
|---|---|
DJANGO_SECRET_KEY | Django secret key |
DJANGO_ALLOWED_HOSTS | Comma-separated allowed hosts |
DATABASE_URL | PostgreSQL connection string |
REDIS_URL | Redis connection string |
DJANGO_AWS_ACCESS_KEY_ID | AWS credentials |
DJANGO_AWS_SECRET_ACCESS_KEY | AWS credentials |
DJANGO_AWS_STORAGE_BUCKET_NAME | S3 bucket name |
STRIPE_API_SECRET | Stripe secret key |
STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret |
OPENAI_API_KEY | For embeddings and LLM inference |
FRONT_END_BASE_URL | Frontend URL |
Optional
| Variable | Default | Description |
|---|---|---|
DJANGO_SECURE_SSL_REDIRECT | True | SSL redirect |
SENTRY_DSN | — | Sentry error tracking |
SENTRY_ENVIRONMENT | production | Sentry environment tag |
SENTRY_TRACES_SAMPLE_RATE | 0.0 | Performance monitoring sample rate |
DJANGO_AWS_S3_REGION_NAME | — | AWS region |
DJANGO_AWS_S3_CUSTOM_DOMAIN | — | CloudFront domain |
RESEND_API_KEY | — | Email provider API key |
CELERY_FLOWER_USER | — | Flower dashboard username |
CELERY_FLOWER_PASSWORD | — | Flower dashboard password |
ANTHROPIC_API_KEY | — | Anthropic LLM provider |
GOOGLE_API_KEY | — | Google LLM provider |
GROQ_API_KEY | — | Groq LLM provider |
DEEPSEEK_API_KEY | — | DeepSeek LLM provider |
SERPAPI_API_KEY | — | Web search tool |
WEATHERAPI_COM_API_KEY | — | Weather tool |
GOOGLE_MAPS_API_KEY | — | Location tool |