This guide explains how to configure The Inventory backend API for different environments using environment variables.
Note: This covers the backend API only. For frontend configuration, see the-inventory-ui.
# 1. Copy environment template (root directory)
cp .env.example .env.local
# 2. Navigate to backend
cd src
# 3. Run migrations
python manage.py migrate
# 4. Create superuser
python manage.py createsuperuser
# 5. Start Django
python manage.py runserver
That’s it! Default values work for local development:
http://localhost:8000# Build image
docker build -t the_inventory .
# Run with environment variables
docker run -p 8000:8000 \
-e SECRET_KEY="your-secret-key" \
-e DATABASE_URL="postgresql://user:pass@db:5432/inventory" \
-e REDIS_URL="redis://redis:6379/0" \
the_inventory
Environment variables are read from your orchestration platform (Render, Docker Compose, Kubernetes, etc.) — not from .env files.
Backend (Django):
┌─────────────────────────────────────────┐
│ OS Environment Variables │ ← From platform (Render, K8s, Docker, etc.)
│ .env file (root directory) │ ← From .env or .env.local
│ Code defaults (settings/*.py) │ ← Fallback defaults
└─────────────────────────────────────────┘
Priority: OS environment > .env file > code defaults
Note: Files in
.gitignore(.env,.env.local) are never committed — you must set environment variables on your platform (Render, Docker, K8s, etc.) for production.
The project uses split Django settings:
| File | When Used | Debug | Database | Purpose |
|---|---|---|---|---|
the_inventory/settings/dev.py |
Local development | True |
SQLite | Fast iteration, all features enabled |
the_inventory/settings/production.py |
Render, Docker, K8s | False |
PostgreSQL (required) | Security hardening, optimized defaults |
the_inventory/settings/base.py |
Always | — | — | Shared config (apps, middleware, templates) |
Selection: DJANGO_SETTINGS_MODULE environment variable (default: production in containers, dev locally)
Required and important variables for both development and production.
SECRET_KEYdev-insecure-xxx in developmentSECRET_KEY="your-very-long-random-string-here"
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
ALLOWED_HOSTSlocalhost,127.0.0.1 (development)https:// prefix, no paths# Local development (default)
ALLOWED_HOSTS=localhost,127.0.0.1
# Production with custom domain
ALLOWED_HOSTS=api.example.com,app.example.com
# Render deployment
ALLOWED_HOSTS=my-service.onrender.com
# Multi-tenant SaaS (all subdomains)
ALLOWED_HOSTS=.example.com # (matches *.example.com and example.com)
https://api.example.com, https://api.example.com/apiapi.example.com, .example.comDJANGO_LOG_LEVELDEBUG, INFO, WARNING, ERROR, CRITICAL)INFODEBUG — Trace authorization, middleware, or request issuesINFO — Standard production loggingWARNING, ERROR — Suppress debug output in strict environmentsDJANGO_LOG_LEVEL=DEBUG # Use briefly to troubleshoot; revert to INFO
LANGUAGE_CODE & TIME_ZONE (Optional)en-us / UTCLANGUAGE_CODE=en-us
TIME_ZONE=America/New_York
TIME_ZONE=Europe/London
TIME_ZONE=Asia/Tokyo
DATABASE_URLdb.sqlite3) in developmentpostgresql://[user]:[password]@[host]:[port]/[database]
# Local PostgreSQL (development)
DATABASE_URL=postgresql://postgres:password@localhost:5432/the_inventory
# Render PostgreSQL (managed)
DATABASE_URL=postgresql://the_inventory_db_user:abc123@dpg-xyz.render-postgresql.com:5432/the_inventory_db
# AWS RDS
DATABASE_URL=postgresql://admin:SecurePass@inventory-db.xyz.rds.amazonaws.com:5432/inventory
# Local Docker Compose
DATABASE_URL=postgresql://postgres:postgres@db:5432/the_inventory
STATIC_URL & MEDIA_URL (Optional)/static/ / /media/# Local development (default)
STATIC_URL=/static/
MEDIA_URL=/media/
# Cloud storage (S3, GCS)
STATIC_URL=https://cdn.example.com/static/
MEDIA_URL=https://storage.googleapis.com/my-bucket/media/
python manage.py collectstaticREDIS_URLredis://localhost:6379/0LocMemCache)redis://[host]:[port]/[db_number]
redis://:password@[host]:[port]/[db_number]
# Local Redis (default)
REDIS_URL=redis://localhost:6379/0
# Render Redis (managed)
REDIS_URL=redis://default:your-password@redis-xyz.render.com:10456
# AWS ElastiCache
REDIS_URL=redis://:your-auth-token@my-cache.cache.amazonaws.com:6379/0
# Local Docker Compose
REDIS_URL=redis://redis:6379/0
CELERY_BROKER_URLREDIS_URL if not specifiedCELERY_BROKER_URL=redis://localhost:6379/1
CELERY_TASK_ALWAYS_EAGERtrue, 1, yes, or false, 0, no)falseCELERY_TASK_ALWAYS_EAGER=true # Dev: tasks run immediately
CELERY_TASK_ALWAYS_EAGER=false # Prod: tasks queued asynchronously
FRONTEND_URLhttp://localhost:3000# Local development
FRONTEND_URL=http://localhost:3000
# Production
FRONTEND_URL=https://app.example.com
# Staging
FRONTEND_URL=https://staging.example.com
PUBLIC_BASE_URL (Optional)ALLOWED_HOSTS or http://127.0.0.1:8000PUBLIC_BASE_URL=https://api.example.com
WAGTAILADMIN_BASE_URL (Optional)/admin/)PUBLIC_BASE_URL or http://127.0.0.1:8000https://api.example.com/admin/”)WAGTAILADMIN_BASE_URL=https://api.example.com
WAGTAIL_SITE_NAME (Optional)the_inventoryWAGTAIL_SITE_NAME="My Company Inventory"
ENABLE_PUBLIC_TENANT_REGISTRATIONfalsetrue — SaaS multi-tenant model (anyone can sign up and create an organization)false — Self-hosted or invite-only (only admins create organizations)ENABLE_PUBLIC_TENANT_REGISTRATION=true # SaaS mode
ENABLE_PUBLIC_TENANT_REGISTRATION=false # Self-hosted mode
AUDIT_TENANT_ACCESStruetrue — Standard; enables compliance/security auditingfalse — High-traffic systems where audit overhead is a concernAUDIT_TENANT_ACCESS=true # Enable audit logging
CORS_ALLOWED_ORIGINShttp://localhost:3000,http://localhost:5173 (dev)# Local development (default)
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
# Production
CORS_ALLOWED_ORIGINS=https://app.example.com
# Multiple frontends
CORS_ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com
# Wildcard subdomains (not recommended)
CORS_ALLOWED_ORIGINS=https://*.example.com
CORS_ALLOW_ALL_ORIGINSfalseCORS_ALLOW_ALL_ORIGINS=true # Dev only!
CORS_ALLOW_CREDENTIALStruetrue for stateless JWT authCORS_ALLOW_CREDENTIALS=true
CORS_EXTRA_HEADERS (Optional)CORS_EXTRA_HEADERS=X-Custom-Header,X-API-Version
CSRF_TRUSTED_ORIGINSCORS_ALLOWED_ORIGINS if not setCSRF_TRUSTED_ORIGINS=https://app.example.com
JWT_COOKIE_SAMESITE, JWT_COOKIE_SECURE)SameSite=Lax, Secure=falseSameSite=Lax, Secure=trueJWT_COOKIE_SAMESITE=None
JWT_COOKIE_SECURE=true
USE_X_FORWARDED_PROTOtrue in production, false in devX-Forwarded-Proto header from reverse proxies/load balancersUSE_X_FORWARDED_PROTO=true # Trust load balancer headers (production)
API_PAGE_SIZE25API_PAGE_SIZE=50 # Return 50 items per page instead of 25
JWT_ACCESS_TOKEN_MINUTES3030 — Standard security5 — High security (frequent refreshes)60+ — Less-secure, longer-lived tokensJWT_ACCESS_TOKEN_MINUTES=15 # Short-lived tokens for security
JWT_REFRESH_TOKEN_DAYS7JWT_REFRESH_TOKEN_DAYS=30 # Refresh tokens valid for 30 days
The system uses HTTP-only cookies for secure browser-based JWT authentication. These settings control how JWT tokens are transmitted via cookies and ensure cookies work correctly in both development (localhost) and production (subdomains) scenarios.
Important: JWT cookies cannot be shared across mismatched hostnames (e.g.,
localhostvs127.0.0.1). Ensure your frontend and backend use consistent hostnames.
JWT_COOKIE_DOMAINNone (empty)None (same-domain only)None (unset) — Bind cookie to exact request domain (development default)".example.com" — Share cookie across subdomains *.example.com (production with subdomains)"localhost" — Explicitly set for localhost development (rarely needed)# Development (localhost only) — leave unset
JWT_COOKIE_DOMAIN=
# Production with subdomains (api.example.com, app.example.com, etc.)
JWT_COOKIE_DOMAIN=.example.com
localhost:3000 and backend on 127.0.0.1:8000, cookies won’t be shared due to domain mismatch. Solution: Use consistent hostnames (both localhost or both actual domain).JWT_COOKIE_PATH// — Available to entire application/api/ — Available only to /api/* paths (rarely needed)JWT_COOKIE_PATH=/
JWT_COOKIE_SECUREtrue or false)false (development), true (production)false — Allow cookies over HTTP (development only, insecure)true — Require HTTPS (production security requirement)true in production. Only set to false for local development.# Local development (HTTP)
JWT_COOKIE_SECURE=false
# Production (HTTPS required)
JWT_COOKIE_SECURE=true
JWT_COOKIE_SAMESITELax, Strict, or None)LaxLax — Safe default; cookies sent on same-site requests and safe cross-site requests (like following links)Strict — Strongest protection; cookies only sent on same-site requests (may break legitimate cross-site requests)None — Allow cross-site cookie transmission; requires JWT_COOKIE_SECURE=true and HTTPS# Standard development and production
JWT_COOKIE_SAMESITE=Lax
# Cross-origin SPA (app.example.com calling api.example.com) with HTTPS
JWT_COOKIE_SAMESITE=None
JWT_COOKIE_SECURE=true
JWT_ACCESS_TOKEN_COOKIE_MAX_AGE300 (5 minutes)JWT_ACCESS_TOKEN_MINUTES lifetime (default 30 minutes in token claim, but 5-minute cookie)JWT_ACCESS_TOKEN_COOKIE_MAX_AGE=300 # 5 minutes (default)
JWT_ACCESS_TOKEN_COOKIE_MAX_AGE=600 # 10 minutes
JWT_ACCESS_TOKEN_COOKIE_MAX_AGE=1800 # 30 minutes
JWT_REFRESH_TOKEN_COOKIE_MAX_AGE604800 (7 days)JWT_REFRESH_TOKEN_COOKIE_MAX_AGE=604800 # 7 days (default)
JWT_REFRESH_TOKEN_COOKIE_MAX_AGE=2592000 # 30 days
Development (Single Machine with localhost):
# Frontend: http://localhost:3000
# Backend: http://localhost:8000
JWT_COOKIE_DOMAIN= # (unset, same-domain only)
JWT_COOKIE_PATH=/
JWT_COOKIE_SECURE=false # (allow HTTP)
JWT_COOKIE_SAMESITE=Lax
JWT_ACCESS_TOKEN_COOKIE_MAX_AGE=300
JWT_REFRESH_TOKEN_COOKIE_MAX_AGE=604800
Production (Subdomain Sharing over HTTPS):
# Frontend: https://app.example.com
# Backend: https://api.example.com
JWT_COOKIE_DOMAIN=.example.com # Share across subdomains
JWT_COOKIE_PATH=/
JWT_COOKIE_SECURE=true # HTTPS required
JWT_COOKIE_SAMESITE=Lax
JWT_ACCESS_TOKEN_COOKIE_MAX_AGE=300
JWT_REFRESH_TOKEN_COOKIE_MAX_AGE=604800
Production (Cross-Origin SPA over HTTPS):
# Frontend: https://widgets.example.com
# Backend: https://api.different.com
JWT_COOKIE_DOMAIN=.different.com
JWT_COOKIE_PATH=/
JWT_COOKIE_SECURE=true # HTTPS required
JWT_COOKIE_SAMESITE=None # Cross-site cookies
JWT_ACCESS_TOKEN_COOKIE_MAX_AGE=300
JWT_REFRESH_TOKEN_COOKIE_MAX_AGE=604800
STOCK_CACHE_TTL_SECONDS600 (10 minutes)STOCK_CACHE_TTL_SECONDS=300 # Cache for 5 minutes
STOCK_CACHE_TTL_SECONDS=3600 # Cache for 1 hour
DASHBOARD_CACHE_TTL_SECONDS300 (5 minutes)DASHBOARD_CACHE_TTL_SECONDS=60 # Cache for 1 minute
API_DOC_TITLE, API_DOC_DESCRIPTION, API_DOC_VERSIONThe Inventory API, RESTful API for The Inventory, 1.0.0API_DOC_TITLE="My Company - Inventory API"
API_DOC_DESCRIPTION="REST API for managing products, stock, and movements"
API_DOC_VERSION=2.0.0
EMAIL_BACKENDdjango.core.mail.backends.console.EmailBackend (dev), django.core.mail.backends.smtp.EmailBackend (prod)EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend # Print to console (dev)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend # SMTP server (prod)
EMAIL_BACKEND=django.core.mail.backends.locmem.EmailBackend # In-memory (testing)
EMAIL_HOST, EMAIL_PORT, EMAIL_USE_TLS, EMAIL_USE_SSLsmtp.gmail.com, 587, true, false# Gmail
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=true
EMAIL_USE_SSL=false
# Custom SMTP
EMAIL_HOST=mail.example.com
EMAIL_PORT=25
EMAIL_USE_TLS=false
EMAIL_USE_SSL=false
EMAIL_HOST_USER, EMAIL_HOST_PASSWORDEMAIL_HOST_USER=noreply@example.com
EMAIL_HOST_PASSWORD=your-app-password # Use app-specific password for Gmail
DEFAULT_FROM_EMAILbash
DEFAULT_FROM_EMAIL=noreply@example.com
—| Variable | Dev Default | Notes |
|---|---|---|
DEBUG |
True |
Full error pages, static file serving |
SECRET_KEY |
insecure-dev-key |
Insecure but fine for local |
ALLOWED_HOSTS |
* |
Accept all hosts locally |
DATABASE_URL |
SQLite (db.sqlite3) | File-based, no setup needed |
REDIS_URL |
Not required | Uses in-memory cache if not set |
CELERY_TASK_ALWAYS_EAGER |
true |
Tasks run synchronously |
EMAIL_BACKEND |
console |
Emails printed to console |
CORS_ALLOWED_ORIGINS |
http://localhost:3000,http://localhost:5173 |
Local frontend origins |
JWT_COOKIE_SECURE |
false |
Allow JWT cookies over HTTP |
Result:
| Variable | Production Default | Notes |
|---|---|---|
DEBUG |
False |
Error pages, no stack traces |
SECRET_KEY |
Required | Must be set via platform secrets |
ALLOWED_HOSTS |
Required | Must match your domain |
DATABASE_URL |
Required | PostgreSQL connection string |
REDIS_URL |
Optional | Recommended for caching/Celery |
CELERY_TASK_ALWAYS_EAGER |
false |
Queue tasks to Redis broker |
EMAIL_BACKEND |
smtp |
Use real SMTP server |
CORS_ALLOWED_ORIGINS |
Not set — must override | Your production frontend URL(s) |
JWT_COOKIE_SECURE |
true |
Only send JWT cookies over HTTPS |
Result:
ManifestStaticFilesStorage)ValueError if missing)—## Setup Guides
git clone https://github.com/Ndevu12/the_inventory.git
cd the_inventory
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
pip install -r requirements-dev.txt # For testing/linting tools
cp .env.example .env.local
python manage.py migrate
python manage.py createsuperuser
python manage.py seed_database --clear --create-default
python manage.py runserver
Visit: http://localhost:8000/admin/
cd frontend
cp .env.local.example .env.local
yarn install
yarn dev
Visit: http://localhost:3000
http://localhost:8000http://localhost:3000http://localhost:8000/admin/http://localhost:8000/api/v1/The system uses HTTP-only cookies for JWT authentication. For cookies to work correctly between frontend and backend, both must use the same hostname:
✅ Correct (will work):
http://localhost:3000 → Backend: http://localhost:8000http://127.0.0.1:3000 → Backend: http://127.0.0.1:8000 (not typically used)❌ Incorrect (cookies won’t be shared):
http://localhost:3000 → Backend: http://127.0.0.1:8000 (domain mismatch)http://127.0.0.1:3000 → Backend: http://localhost:8000 (domain mismatch)To verify:
http://localhost:3000access_token and refresh_token cookies are present for localhost127.0.0.1 but frontend URL shows localhost, you have a hostname mismatch# Build image
docker build -t the_inventory:latest .
# Run with minimal environment (uses defaults)
docker run -p 8000:8000 \
-e SECRET_KEY="$(python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())')" \
-e ALLOWED_HOSTS="localhost,127.0.0.1" \
the_inventory:latest
Connect your GitHub repository to Render
Create a Web Service with these Environment variables:
DJANGO_SETTINGS_MODULE production
SECRET_KEY <generate and paste here>
ALLOWED_HOSTS your-service.onrender.com
DATABASE_URL <Render PostgreSQL connection string>
REDIS_URL <Render Redis connection string>
FRONTEND_URL https://your-frontend.vercel.app
AUTO_SEED_DATABASE false # true only for initial setup
Database will auto-migrate via entrypoint.sh
Fork the repository
Create new Vercel project from frontend/ directory
Set these Environment variables:
NEXT_PUBLIC_API_URL https://your-service.onrender.com/api/v1
NEXT_PUBLIC_APP_NAME The Inventory - Production
Deploy — Vercel will build and deploy automatically
Before deploying to production:
SECRET_KEYEMAIL_HOST_PASSWORD (if using SMTP)DATABASE_URL)ALLOWED_HOSTS matches your domain(s)FRONTEND_URL matches your frontend domain*)example.com or both subdomain.example.com, not mixed)JWT_COOKIE_SECURE=true (HTTPS required)JWT_COOKIE_DOMAIN=.example.com (for subdomain sharing) or blank (for same-domain)JWT_COOKIE_SAMESITE set appropriately (Lax for same-domain, None for cross-origin with Secure=true)python manage.py migratepython manage.py collectstaticDEFAULT_FROM_EMAIL configuredDJANGO_LOG_LEVEL=INFO (at least)NEXT_PUBLIC_API_URL points to correct APIgettext)locale/<lang>/LC_MESSAGES/django.po (see LOCALE_PATHS in settings).Extract / update messages (always exclude virtualenv and frontend dependencies so xgettext does not scan them):
python manage.py makemessages -l fr -l sw -l rw -l es \
--ignore=venv --ignore=.venv --ignore=frontend/node_modules --ignore=node_modules
Compile .po → .mo (required for runtime translations):
python manage.py compilemessages
Project catalogs under locale/**/LC_MESSAGES/*.mo are tracked in git (see .gitignore).
django.utils.translation.gettext_lazy as _ (models/forms) or gettext in views; use {% trans %} / {% blocktrans %} in templates.Accept-Language / LocaleMiddleware once LANGUAGES includes that code and the catalog is compiled.next-intl)frontend/public/locales/<locale>.json (e.g. en, fr, sw, rw, es, ar), loaded in frontend/src/i18n/load-messages.ts.frontend/scripts/ and run yarn locale:merge from frontend/ — see I18N_FRONTEND.md. For other namespaces you may edit public/locales/*.json directly (avoid editing merged subtrees by hand or the next merge will overwrite them).useTranslations('TopLevelNamespace') on the client (nested keys: t('child.grandchild')); getTranslations / getMessages on the server (see frontend/src/app/[locale]/layout.tsx).Error:
400 Bad Request — Invalid HTTP_HOST header: 'my-service.onrender.com'.
Expected one of: ['localhost', '127.0.0.1']
Solution:
Add your domain to ALLOWED_HOSTS:
ALLOWED_HOSTS=localhost,127.0.0.1,my-service.onrender.com
Error (browser console):
Access to XMLHttpRequest at 'http://localhost:8000/api/v1/...' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Solution:
Ensure backend has frontend origin in CORS_ALLOWED_ORIGINS:
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
If frontend is on different machine/IP:
CORS_ALLOWED_ORIGINS=http://192.168.1.100:3000
Error:
ValueError: SECRET_KEY is required for production deployments
Solution:
Set SECRET_KEY via platform environment:
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"Never hardcode secrets in .env files committed to git!
Error:
django.core.exceptions.ImproperlyConfigured:
The 'django.contrib.postgres' app is available,
but not installed. (No installed app with label 'postgres'.)
Solution:
Ensure DATABASE_URL is set correctly:
# Format: postgresql://[user]:[password]@[host]:[port]/[database]
DATABASE_URL=postgresql://postgres:password@localhost:5432/the_inventory
Check connection:
# Test connection locally
psql postgresql://postgres:password@localhost:5432/the_inventory -c "SELECT 1"
Error:
ConnectionError: Error 111 connecting to localhost:6379. Connection refused.
Solution: Redis is optional. If you don’t have Redis running:
REDIS_URL unset — Django will use in-memory cache# macOS
brew install redis && redis-server
# Ubuntu/Debian
sudo apt-get install redis-server && redis-server
# Docker
docker run -p 6379:6379 redis:latest
Error:
No handlers could be found for logger "django.request"
Connection refused connecting to SMTP server
Solution:
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend # Dev only
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=true
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password # Use app-specific password for Gmail!
DEFAULT_FROM_EMAIL=noreply@example.com
python manage.py shell
>>> from django.core.mail import send_mail
>>> send_mail(
... 'Test',
... 'This is a test email',
... 'noreply@example.com',
... ['recipient@example.com']
... )
Error:
TypeError: seed_database() got unexpected keyword argument 'seed_models'
Solution:
The environment variable is SEED_MODELS (with underscore), not SEED-MODELS:
# ✅ Correct
SEED_MODELS=categories,products
# ❌ Wrong
SEED_MODELS=categories,products # (typo in env var name)
Error:
You have unapplied migrations for apps: inventory, ...
Solution: Run migrations:
python manage.py migrate
Or in Docker, migrations auto-run via entrypoint.sh.
If you’re stuck:
python manage.py runserver console outputdocker logs <container-id>DJANGO_LOG_LEVEL=DEBUG
| Category | Variables |
|---|---|
| Core | SECRET_KEY, ALLOWED_HOSTS, DJANGO_LOG_LEVEL |
| Database | DATABASE_URL, STATIC_URL, MEDIA_URL |
| Caching | REDIS_URL, CELERY_BROKER_URL, CELERY_TASK_ALWAYS_EAGER |
| URLs | FRONTEND_URL, PUBLIC_BASE_URL, WAGTAILADMIN_BASE_URL |
| Security | CORS_ALLOWED_ORIGINS, CSRF_TRUSTED_ORIGINS, JWT_COOKIE_SAMESITE, JWT_COOKIE_SECURE |
| Tenants | ENABLE_PUBLIC_TENANT_REGISTRATION, AUDIT_TENANT_ACCESS |
| API | API_PAGE_SIZE, JWT_ACCESS_TOKEN_MINUTES, JWT_REFRESH_TOKEN_DAYS |
| Caching TTLs | STOCK_CACHE_TTL_SECONDS, DASHBOARD_CACHE_TTL_SECONDS |
| Docs | API_DOC_TITLE, API_DOC_DESCRIPTION, API_DOC_VERSION |
EMAIL_BACKEND, EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, DEFAULT_FROM_EMAIL |
|
| Seeding | AUTO_SEED_DATABASE, SEED_CLEAR, SEED_QUIET, SEED_TENANT, SEED_MODELS |
| Frontend | NEXT_PUBLIC_API_URL, NEXT_PUBLIC_APP_NAME |
Backend (.env or platform environment):
SECRET_KEY, ALLOWED_HOSTS, DJANGO_LOG_LEVEL, LANGUAGE_CODE, TIME_ZONEDATABASE_URL, STATIC_URL, MEDIA_URLREDIS_URL, CELERY_BROKER_URL, CELERY_TASK_ALWAYS_EAGERFRONTEND_URL, PUBLIC_BASE_URL, WAGTAILADMIN_BASE_URL, WAGTAIL_SITE_NAMEENABLE_PUBLIC_TENANT_REGISTRATION, AUDIT_TENANT_ACCESSCORS_ALLOWED_ORIGINS, CORS_ALLOW_ALL_ORIGINS, CORS_ALLOW_CREDENTIALS, CORS_EXTRA_HEADERS, CSRF_TRUSTED_ORIGINS, JWT_COOKIE_SAMESITE, JWT_COOKIE_SECURE, USE_X_FORWARDED_PROTOAPI_PAGE_SIZE, JWT_ACCESS_TOKEN_MINUTES, JWT_REFRESH_TOKEN_DAYSSTOCK_CACHE_TTL_SECONDS, DASHBOARD_CACHE_TTL_SECONDSAPI_DOC_TITLE, API_DOC_DESCRIPTION, API_DOC_VERSIONEMAIL_BACKEND, EMAIL_HOST, EMAIL_PORT, EMAIL_USE_TLS, EMAIL_USE_SSL, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, DEFAULT_FROM_EMAILAUTO_SEED_DATABASE, SEED_CLEAR, SEED_QUIET, SEED_TENANT, SEED_MODELSFrontend (.env.local):
NEXT_PUBLIC_API_URL (required)NEXT_PUBLIC_APP_NAME (optional)