# Environment Variables Reference All configuration for the Orion platform is managed through environment variables, loaded via Pydantic Settings from an `.env` file or the process environment. This page provides a complete reference for every variable recognised by `app/core/config.py`. Variables are read at startup and exposed through the `settings` singleton. In most cases the defaults are tuned for local development; production deployments **must** override the security-sensitive values listed in the [Production Checklist](#production-checklist) at the bottom of this page. --- ## Core / Project Metadata used in the OpenAPI schema and health endpoints. | Variable | Description | Default | Required | |---|---|---|---| | `PROJECT_NAME` | Display name shown in API docs and health responses | `Orion - Multi-Store Marketplace Platform` | No | | `VERSION` | Semantic version reported by the platform | `2.2.0` | No | --- ## Database !!! danger "Production requirement" You **must** set `DATABASE_URL` to a real PostgreSQL connection string in every non-development environment. The default value contains a placeholder password and should never be used in production. | Variable | Description | Default | Required | |---|---|---|---| | `DATABASE_URL` | PostgreSQL connection string (`postgresql://user:pass@host:port/db`) | `postgresql://orion_user:secure_password@localhost:5432/orion_db` | **Yes** | --- ## Admin Initialisation Used by `init_production.py` and the database seeder to create the initial platform administrator account. !!! warning "Change the default password" The default `ADMIN_PASSWORD` is `admin123`. The production validation check will emit a warning if this value is left unchanged. | Variable | Description | Default | Required | |---|---|---|---| | `ADMIN_EMAIL` | Email address for the initial admin account | `admin@orion.lu` | No | | `ADMIN_USERNAME` | Username for the initial admin account | `admin` | No | | `ADMIN_PASSWORD` | Password for the initial admin account | `admin123` | No (but **must change** in production) | | `ADMIN_FIRST_NAME` | First name of the admin user | `Platform` | No | | `ADMIN_LAST_NAME` | Last name of the admin user | `Administrator` | No | --- ## JWT Authentication Controls JSON Web Token generation and expiry. !!! danger "Production requirement" `JWT_SECRET_KEY` **must** be replaced with a strong random value. Generate one with: ```bash openssl rand -hex 32 ``` | Variable | Description | Default | Required | |---|---|---|---| | `JWT_SECRET_KEY` | Secret used to sign and verify JWTs | `change-this-in-production` | **Yes** | | `JWT_EXPIRE_HOURS` | Hours component of the token lifetime | `24` | No | | `JWT_EXPIRE_MINUTES` | Minutes component of the token lifetime | `30` | No | --- ## API Server Settings passed to Uvicorn when the application starts. | Variable | Description | Default | Required | |---|---|---|---| | `API_HOST` | Bind address for the API server | `0.0.0.0` | No | | `API_PORT` | Port the API server listens on | `8000` | No | | `DEBUG` | Enable debug mode (extra logging, auto-reload) | `True` | No (set `False` in production) | --- ## Documentation | Variable | Description | Default | Required | |---|---|---|---| | `DOCUMENTATION_URL` | URL where the MkDocs site is served | `http://localhost:8001` | No | --- ## Security / Middleware !!! warning "Restrict allowed hosts" The default `ALLOWED_HOSTS` value of `["*"]` accepts requests with any `Host` header. In production, restrict this to your actual domain names. | Variable | Description | Default | Required | |---|---|---|---| | `ALLOWED_HOSTS` | JSON list of permitted `Host` header values | `["*"]` | No (but **restrict** in production) | | `RATE_LIMIT_ENABLED` | Enable request rate limiting | `True` | No | | `RATE_LIMIT_REQUESTS` | Maximum number of requests per window | `100` | No | | `RATE_LIMIT_WINDOW` | Rate limit window duration in seconds | `3600` | No | --- ## Logging | Variable | Description | Default | Required | |---|---|---|---| | `LOG_LEVEL` | Python log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`) | `INFO` | No | | `LOG_FILE` | Path to a log file; `None` means stdout only | `None` | No | --- ## Platform Domain Controls the base domain for store subdomains and custom-domain features. | Variable | Description | Default | Required | |---|---|---|---| | `PLATFORM_DOMAIN` | Root domain under which store subdomains are created | `wizard.lu` | No | | `ALLOW_CUSTOM_DOMAINS` | Allow stores to use their own domain names | `True` | No | | `REQUIRE_DOMAIN_VERIFICATION` | Require DNS verification before activating a custom domain | `True` | No | | `SSL_PROVIDER` | SSL certificate provider (`letsencrypt`, `cloudflare`, `manual`) | `letsencrypt` | No | | `AUTO_PROVISION_SSL` | Automatically provision SSL certificates for custom domains | `False` | No | | `DNS_VERIFICATION_PREFIX` | TXT record prefix used for domain ownership verification | `_orion-verify` | No | | `DNS_VERIFICATION_TTL` | TTL in seconds for DNS verification records | `3600` | No | --- ## Platform Limits Guard-rails for multi-tenant resource usage. | Variable | Description | Default | Required | |---|---|---|---| | `MAX_STORES_PER_USER` | Maximum number of stores a single user can own | `5` | No | | `MAX_TEAM_MEMBERS_PER_STORE` | Maximum team members allowed per store | `50` | No | | `INVITATION_EXPIRY_DAYS` | Days before a team invitation link expires | `7` | No | --- ## Stripe Billing !!! info "Required for payments" All three Stripe keys must be set to enable subscription billing and payment processing. Obtain them from the [Stripe Dashboard](https://dashboard.stripe.com/apikeys). | Variable | Description | Default | Required | |---|---|---|---| | `STRIPE_SECRET_KEY` | Stripe secret API key | `""` (empty) | Yes (for payments) | | `STRIPE_PUBLISHABLE_KEY` | Stripe publishable API key | `""` (empty) | Yes (for payments) | | `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret | `""` (empty) | Yes (for payments) | | `STRIPE_TRIAL_DAYS` | Length of the free trial period in days | `30` | No | --- ## Email Configuration Orion supports multiple email providers. Set `EMAIL_PROVIDER` to choose one, then configure the matching provider-specific variables below. | Variable | Description | Default | Required | |---|---|---|---| | `EMAIL_PROVIDER` | Email transport backend (`smtp`, `sendgrid`, `mailgun`, `ses`) | `smtp` | No | | `EMAIL_FROM_ADDRESS` | Sender address for outgoing emails | `noreply@orion.lu` | No | | `EMAIL_FROM_NAME` | Sender display name | `Orion` | No | | `EMAIL_REPLY_TO` | Optional reply-to address | `""` (empty) | No | | `EMAIL_ENABLED` | Master switch to enable/disable all outgoing email | `True` | No | | `EMAIL_DEBUG` | Log emails to console instead of sending (development only) | `False` | No | ### SMTP Settings Used when `EMAIL_PROVIDER=smtp`. | Variable | Description | Default | Required | |---|---|---|---| | `SMTP_HOST` | SMTP server hostname | `localhost` | No | | `SMTP_PORT` | SMTP server port | `587` | No | | `SMTP_USER` | SMTP authentication username | `""` (empty) | No | | `SMTP_PASSWORD` | SMTP authentication password | `""` (empty) | No | | `SMTP_USE_TLS` | Use STARTTLS (port 587) | `True` | No | | `SMTP_USE_SSL` | Use implicit SSL (port 465) | `False` | No | ### SendGrid Settings Used when `EMAIL_PROVIDER=sendgrid`. | Variable | Description | Default | Required | |---|---|---|---| | `SENDGRID_API_KEY` | SendGrid API key | `""` (empty) | Yes (if using SendGrid) | ### Mailgun Settings Used when `EMAIL_PROVIDER=mailgun`. | Variable | Description | Default | Required | |---|---|---|---| | `MAILGUN_API_KEY` | Mailgun API key | `""` (empty) | Yes (if using Mailgun) | | `MAILGUN_DOMAIN` | Mailgun sending domain | `""` (empty) | Yes (if using Mailgun) | ### Amazon SES Settings Used when `EMAIL_PROVIDER=ses`. | Variable | Description | Default | Required | |---|---|---|---| | `AWS_ACCESS_KEY_ID` | AWS access key for SES | `""` (empty) | Yes (if using SES) | | `AWS_SECRET_ACCESS_KEY` | AWS secret key for SES | `""` (empty) | Yes (if using SES) | | `AWS_REGION` | AWS region for the SES endpoint | `eu-west-1` | No | --- ## Storefront Defaults Default locale and currency applied to new storefronts. Individual stores can override these through the admin interface or the `AdminSetting` database table. | Variable | Description | Default | Required | |---|---|---|---| | `DEFAULT_STOREFRONT_LOCALE` | Locale code for currency and number formatting | `fr-LU` | No | | `DEFAULT_CURRENCY` | ISO 4217 currency code | `EUR` | No | --- ## Seed Data Controls the volume of demo data generated by the database seeder. | Variable | Description | Default | Required | |---|---|---|---| | `SEED_DEMO_STORES` | Number of demo stores to create | `3` | No | | `SEED_CUSTOMERS_PER_STORE` | Number of demo customers per store | `15` | No | | `SEED_PRODUCTS_PER_STORE` | Number of demo products per store | `20` | No | | `SEED_ORDERS_PER_STORE` | Number of demo orders per store | `10` | No | --- ## Celery / Redis Background task processing. When `USE_CELERY` is `False`, tasks fall back to FastAPI's built-in `BackgroundTasks`. !!! tip "Enable Celery in production" Set `USE_CELERY=True` and ensure a Redis instance is reachable at `REDIS_URL` for reliable background task processing. | Variable | Description | Default | Required | |---|---|---|---| | `REDIS_URL` | Redis connection string used as Celery broker and result backend | `redis://localhost:6379/0` | No | | `USE_CELERY` | Use Celery for background tasks instead of FastAPI BackgroundTasks | `False` | No (set `True` in production) | | `FLOWER_URL` | URL of the Flower monitoring dashboard | `http://localhost:5555` | No | | `FLOWER_PASSWORD` | Password for Flower authentication | `changeme` | No (but **change** in production) | --- ## Sentry Error tracking and performance monitoring via [Sentry](https://sentry.io). | Variable | Description | Default | Required | |---|---|---|---| | `SENTRY_DSN` | Sentry Data Source Name; `None` disables Sentry | `None` | No | | `SENTRY_ENVIRONMENT` | Environment tag sent with events (`development`, `staging`, `production`) | `development` | No | | `SENTRY_TRACES_SAMPLE_RATE` | Fraction of transactions sampled for performance monitoring (0.0--1.0) | `0.1` | No | --- ## Monitoring Prometheus metrics and Grafana dashboard integration. | Variable | Description | Default | Required | |---|---|---|---| | `ENABLE_METRICS` | Expose a `/metrics` endpoint for Prometheus scraping | `False` | No (set `True` in production) | | `GRAFANA_URL` | URL of the Grafana instance | `https://grafana.wizard.lu` | No | | `GRAFANA_ADMIN_USER` | Grafana admin username | `admin` | No | | `GRAFANA_ADMIN_PASSWORD` | Grafana admin password | `""` (empty) | No | --- ## Cloudflare R2 Storage Object storage for media uploads. When `STORAGE_BACKEND` is `local`, files are stored on the server filesystem. | Variable | Description | Default | Required | |---|---|---|---| | `STORAGE_BACKEND` | Storage backend to use (`local` or `r2`) | `local` | No | | `R2_ACCOUNT_ID` | Cloudflare account ID | `None` | Yes (if using R2) | | `R2_ACCESS_KEY_ID` | R2 API access key | `None` | Yes (if using R2) | | `R2_SECRET_ACCESS_KEY` | R2 API secret key | `None` | Yes (if using R2) | | `R2_BUCKET_NAME` | R2 bucket name | `orion-media` | No | | `R2_PUBLIC_URL` | Custom public URL for media access (e.g. `https://media.yoursite.com`) | `None` | No | --- ## Cloudflare CDN / Proxy | Variable | Description | Default | Required | |---|---|---|---| | `CLOUDFLARE_ENABLED` | Set to `True` when the application sits behind Cloudflare proxy (adjusts trusted-proxy headers) | `False` | No (set `True` when proxied) | --- ## Production Checklist Before deploying to production, ensure the following variables are set correctly. Items marked **critical** will trigger a startup warning if left at their default values. !!! danger "Critical -- must change" - [x] `DATABASE_URL` -- point to a production PostgreSQL instance - [x] `JWT_SECRET_KEY` -- generate with `openssl rand -hex 32` - [x] `ADMIN_PASSWORD` -- choose a strong, unique password - [x] `DEBUG` -- set to `False` - [x] `ALLOWED_HOSTS` -- restrict to your domain(s) !!! warning "Strongly recommended" - [x] `USE_CELERY` -- set to `True` with a production Redis instance - [x] `FLOWER_PASSWORD` -- change from the default `changeme` - [x] `ENABLE_METRICS` -- set to `True` for observability - [x] `SENTRY_DSN` -- configure for error tracking - [x] `SENTRY_ENVIRONMENT` -- set to `production` - [x] `STORAGE_BACKEND` -- set to `r2` for scalable media storage - [x] `CLOUDFLARE_ENABLED` -- set to `True` if behind Cloudflare proxy !!! info "Required for specific features" - [x] **Payments:** `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`, `STRIPE_WEBHOOK_SECRET` - [x] **Email (SendGrid):** `SENDGRID_API_KEY` - [x] **Email (Mailgun):** `MAILGUN_API_KEY`, `MAILGUN_DOMAIN` - [x] **Email (SES):** `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` - [x] **R2 Storage:** `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY` ### Example `.env` file (production) ```bash # Core DATABASE_URL=postgresql://orion:STRONG_PASSWORD@db.internal:5432/orion JWT_SECRET_KEY=a]3f...your-random-hex-here...9c2b DEBUG=False ALLOWED_HOSTS=["wizard.lu","*.wizard.lu"] # Admin ADMIN_PASSWORD=your-strong-admin-password # Celery / Redis REDIS_URL=redis://redis.internal:6379/0 USE_CELERY=True FLOWER_PASSWORD=a-secure-flower-password # Stripe STRIPE_SECRET_KEY=sk_live_... STRIPE_PUBLISHABLE_KEY=pk_live_... STRIPE_WEBHOOK_SECRET=whsec_... # Email (example: SendGrid) EMAIL_PROVIDER=sendgrid SENDGRID_API_KEY=SG.... # R2 Storage STORAGE_BACKEND=r2 R2_ACCOUNT_ID=your-account-id R2_ACCESS_KEY_ID=your-access-key R2_SECRET_ACCESS_KEY=your-secret-key R2_PUBLIC_URL=https://media.wizard.lu # Monitoring ENABLE_METRICS=True SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 SENTRY_ENVIRONMENT=production CLOUDFLARE_ENABLED=True ```