Configuration
Environment variables and configuration files for the backend
Configuration
Environment Files
Symfony loads environment files in this order (later files override earlier ones):
.env— committed defaults and documentation.env.local— your local overrides (gitignored).env.{APP_ENV}— environment-specific defaults (e.g.,.env.test).env.{APP_ENV}.local— environment-specific local overrides
Real environment variables (set in your shell or Docker) always win over .env files.
Never commit secrets. Put all real credentials in
.env.localor set them as environment variables in your deployment platform.
Environment Variables
Core
| Variable | Description | Example |
|---|---|---|
APP_ENV | Symfony environment | dev, test, prod |
APP_SECRET | Symfony secret (CSRF, signing) | Random 32+ char string |
DATABASE_URL | PostgreSQL connection string | postgresql://app:pass@database:5432/app |
MESSENGER_TRANSPORT_DSN | Message transport | sync:// (dev) or redis://redis:6379/messages |
JWT_PASSPHRASE | Passphrase for JWT key pair | Random string |
CORS_ALLOW_ORIGIN | Allowed CORS origins (regex) | ^https?://(localhost)(:[0-9]+)?$ |
Email / Brevo
| Variable | Description | Example |
|---|---|---|
EMAIL_SENDER_EMAIL | From address for all emails | noreply@yourdomain.com |
EMAIL_SENDER_NAME | From name for all emails | Your App Name |
MAILER_DSN | Symfony Mailer transport | smtp://mailer:1025 (dev) |
BREVO_API_KEY | Brevo API key (production emails) | xkeysib-... |
In development, emails go to Mailpit at http://localhost:8025. In production, emails are sent via the Brevo API.
Stripe
| Variable | Description | Example |
|---|---|---|
STRIPE_SECRET_KEY | Stripe API secret key | sk_test_... or sk_live_... |
STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret | whsec_... |
STRIPE_SUCCESS_URL | Redirect after successful payment | https://yourapp.com/payment/success |
STRIPE_CANCEL_URL | Redirect after cancelled payment | https://yourapp.com/payment/cancel |
Firebase
| Variable | Description | Example |
|---|---|---|
FIREBASE_PROJECT_ID | Firebase project ID | my-app-12345 |
Frontend URLs
| Variable | Description | Example |
|---|---|---|
EMAIL_VALIDATION_REDIRECT_URL | Where users land after email validation | https://yourapp.com/auth/email-verified |
FRONTEND_RESET_PASSWORD_URL | Frontend password reset form | https://yourapp.com/auth/reset-password |
GitHub (Optional)
| Variable | Description | Example |
|---|---|---|
PERSONAL_GITHUB_API_TOKEN | GitHub PAT with admin:org scope | ghp_... |
ORGANIZATION_GITHUB_NAME | GitHub organization name | your-github-org |
Only needed if using the GitHub organization auto-invite feature for paid subscribers.
Config Files
Stripe Plans — config/packages/stripe.yaml
Defines your plan tiers. Supports both one-time and recurring payment models:
parameters:
stripe_plans:
starter:
name: 'Starter Plan'
type: 'one_time'
price_cents: 4900 # $49.00
pro:
name: 'Pro Plan'
type: 'one_time'
price_cents: 14900 # $149.00
After changing plan definitions, sync to Stripe:
docker compose exec php bin/console app:stripe:sync-plans
Brevo Email Templates — config/packages/brevo.yaml
Maps Brevo template IDs to email types:
| Template | Variables |
|---|---|
| Welcome | userName, validationLink |
| Password Changed | userName |
| Password Reset | userName, resetLink |
| GitHub Membership | userName, organizationUrl |
Rate Limiting — config/packages/rate_limiter.yaml
| Limiter | Limit | Window | Scope |
|---|---|---|---|
auth_signup_ip | 5 | 15 minutes | IP |
auth_signup_email | 3 | 15 minutes | |
auth_login_ip | 5 | 15 minutes | IP |
auth_login_email | 5 | 15 minutes | |
auth_logout | 10 | 1 minute | IP |
JWT Configuration
| Setting | Value |
|---|---|
| Access token TTL | 3600s (1 hour) |
| Refresh token TTL | 2592000s (30 days) |
| Refresh token | Single-use (rotated on each refresh) |