# Environment Variables Reference ## Overview This document describes all environment variables used by Headquarter. Variables are categorized by component and purpose. ## Required Variables These variables must be set for the application to function: ### Domains | Variable | Default | Description | |----------|---------|-------------| | `API_DOMAIN` | `localhost` | API server domain (e.g., `api.example.com`) | | `WEB_DOMAIN` | `localhost` | Web frontend domain (e.g., `app.example.com`) | ### Database | Variable | Default | Description | |----------|---------|-------------| | `POSTGRES_USER` | `headquarter` | PostgreSQL username | | `POSTGRES_PASSWORD` | `headquarter` | PostgreSQL password (change in production!) | | `POSTGRES_DB` | `headquarter` | PostgreSQL database name | ### Authentication | Variable | Default | Description | |----------|---------|-------------| | `AUTHENTIK_DOMAIN` | `authentik.local` | Authentik server domain | | `AUTHENTIK_CLIENT_ID` | `headquarter-web` | OAuth client ID from Authentik | | `AUTHENTIK_CLIENT_SECRET` | `change-me` | OAuth client secret (change immediately!) | | `AUTHENTIK_APPLICATION_SLUG` | `headquarter-web` | Authentik application slug | | `SESSION_SECRET` | `change-me-session-secret` | Secret for signing session cookies (min 32 chars) | ## Optional Variables ### Application | Variable | Default | Description | |----------|---------|-------------| | `APP_ENV` | `development` | Environment: `development`, `staging`, `production` | | `LOG_LEVEL` | `INFO` | Logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR` | ### Database | Variable | Default | Description | |----------|---------|-------------| | `DATABASE_URL` | (constructed) | Full PostgreSQL connection URL | | `POSTGRES_HOST` | `postgres` | PostgreSQL hostname | | `POSTGRES_PORT` | `5432` | PostgreSQL port | When `DATABASE_URL` is not set, it's constructed from: ``` postgresql+asyncpg://POSTGRES_USER:POSTGRES_PASSWORD@POSTGRES_HOST:POSTGRES_PORT/POSTGRES_DB ``` ### URLs | Variable | Default | Description | |----------|---------|-------------| | `API_PUBLIC_URL` | (constructed) | Public API URL (e.g., `https://api.example.com`) | | `WEB_PUBLIC_URL` | (constructed) | Public web URL (e.g., `https://app.example.com`) | Constructed from domains when not set: ``` API: https://API_DOMAIN (production) or http://API_DOMAIN:8000 (development) WEB: https://WEB_DOMAIN (production) or http://WEB_DOMAIN:5173 (development) ``` ### Authentik Overrides | Variable | Default | Description | |----------|---------|-------------| | `AUTHENTIK_AUTHORIZE_URL` | (constructed) | OAuth authorization endpoint | | `AUTHENTIK_TOKEN_URL` | (constructed) | OAuth token endpoint | | `AUTHENTIK_JWKS_URL` | (constructed) | JWKS endpoint | | `AUTHENTIK_ISSUER` | (constructed) | OAuth issuer URL | | `AUTHENTIK_AUDIENCE` | `headquarter-web` | Token audience | Constructed URLs: ``` https://AUTHENTIK_DOMAIN/application/o/authorize/ https://AUTHENTIK_DOMAIN/application/o/token/ https://AUTHENTIK_DOMAIN/application/o/AUTHENTIK_APPLICATION_SLUG/jwks/ https://AUTHENTIK_DOMAIN/application/o/AUTHENTIK_APPLICATION_SLUG/ ``` ### Session | Variable | Default | Description | |----------|---------|-------------| | `SESSION_TTL_HOURS` | `24` | Session cookie lifetime in hours | | `COOKIE_DOMAIN` | (none) | Cookie domain (set for cross-subdomain) | | `COOKIE_SECURE` | `true` (prod) | Secure cookie flag | | `COOKIE_SAMESITE` | `lax` | SameSite cookie attribute | ### Storage | Variable | Default | Description | |----------|---------|-------------| | `REPO_BASE_PATH` | `/data/repos` | Base path for git repositories | | `UPLOAD_DIR` | `uploads` | Directory for file uploads | ### Development | Variable | Default | Description | |----------|---------|-------------| | `VITE_API_BASE_URL` | `http://localhost:8000` | Frontend API URL | ## Docker Compose Variables ### Traefik | Variable | Default | Description | |----------|---------|-------------| | `TRAEFIK_NETWORK` | `traefik` | Docker network name for Traefik | | `TRAEFIK_CERT_RESOLVER` | `letsencrypt` | Certificate resolver name | ### Docker Specific | Variable | Default | Description | |----------|---------|-------------| | `COMPOSE_PROJECT_NAME` | `headquarter` | Docker Compose project name | ## Configuration Examples ### Development ```bash APP_ENV=development API_DOMAIN=localhost WEB_DOMAIN=localhost DATABASE_URL=postgresql+asyncpg://headquarter:headquarter@localhost:5432/headquarter AUTHENTIK_DOMAIN=authentik.local AUTHENTIK_CLIENT_ID=headquarter-web AUTHENTIK_CLIENT_SECRET=dev-secret SESSION_SECRET=dev-session-secret-change-in-production VITE_API_BASE_URL=http://localhost:8000 ``` ### Production ```bash APP_ENV=production API_DOMAIN=api.headquarter.example.com WEB_DOMAIN=app.headquarter.example.com POSTGRES_PASSWORD=very-secure-password-here AUTHENTIK_DOMAIN=auth.example.com AUTHENTIK_CLIENT_ID=your-uuid-from-authentik AUTHENTIK_CLIENT_SECRET=your-secret-from-authentik AUTHENTIK_APPLICATION_SLUG=headquarter-web SESSION_SECRET=minimum-32-characters-long-secret-key SESSION_TTL_HOURS=24 COOKIE_DOMAIN=.headquarter.example.com TRAEFIK_NETWORK=web TRAEFIK_CERT_RESOLVER=letsencrypt REPO_BASE_PATH=/data/repos ``` ### Testing ```bash APP_ENV=testing DATABASE_URL=postgresql+asyncpg://headquarter:headquarter@localhost:5432/headquarter_test SESSION_SECRET=test-secret AUTHENTIK_CLIENT_ID=test-client AUTHENTIK_CLIENT_SECRET=test-secret ``` ## Security Checklist Before deploying to production, verify: - [ ] `POSTGRES_PASSWORD` is strong and unique - [ ] `AUTHENTIK_CLIENT_SECRET` is kept secret - [ ] `SESSION_SECRET` is at least 32 characters - [ ] `APP_ENV` is set to `production` - [ ] `COOKIE_SECURE` is enabled - [ ] `COOKIE_DOMAIN` is set for your domain - [ ] No default secrets in production - [ ] `.env` file is not committed to git - [ ] `.env` file has restricted permissions (600) ## Troubleshooting ### Variable Not Set ```bash # Error: "Environment variable not set" # Solution: Export the variable or add to .env file export SESSION_SECRET="your-secret-here" ``` ### Invalid URL ```bash # Error: "Invalid URL" # Solution: Check domain variables don't include protocol # Bad: API_DOMAIN=https://api.example.com # Good: API_DOMAIN=api.example.com ``` ### Database Connection Failed ```bash # Check DATABASE_URL or individual components # Verify PostgreSQL is running # Check credentials match ``` ## Migration from Old Config If upgrading from older versions: 1. `JWT_SECRET` → Removed (not needed with session auth) 2. `ACCESS_TOKEN_TTL_MINUTES` → Removed 3. `REFRESH_TOKEN_TTL_DAYS` → Removed 4. `AUTHENTIK_AUDIENCE` → Now defaults to `AUTHENTIK_CLIENT_ID` 5. `AUTHENTIK_APPLICATION_SLUG` → New variable for URL construction ## Environment Files ### Files Structure ``` headquarter/ ├── .env # Main environment (not committed) ├── .env.example # Example/template ├── apps/ │ ├── api/ │ │ └── .env # API-specific overrides │ └── web/ │ └── .env # Frontend-specific overrides └── docker-compose.traefik.yml # References .env ``` ### Loading Order 1. System environment variables 2. `.env` file in project root 3. Component-specific `.env` files 4. Default values in code Later values override earlier ones. ## Validation The application validates required variables on startup: ```python # Missing critical variable if not settings.session_secret or settings.session_secret == "change-me": logger.warning("SESSION_SECRET not configured properly!") # Invalid configuration if settings.app_env == "production" and "localhost" in settings.api_domain: logger.warning("Using localhost in production!") ``` ## Best Practices 1. **Never commit `.env` files** 2. **Use strong passwords** for database and secrets 3. **Rotate secrets** regularly 4. **Use different secrets** per environment 5. **Document custom variables** in this file 6. **Validate configuration** before deployment