# Flask settings # CRITICAL: Change SECRET_KEY in production! Used for sessions, cookies, and CSRF tokens. # Generate a secure key with: python -c "import secrets; print(secrets.token_hex(32))" # The same key must be used across restarts and all app replicas. SECRET_KEY=your-secret-key-here FLASK_ENV=production FLASK_DEBUG=false # Database settings DATABASE_URL=postgresql+psycopg2://timetracker:timetracker@db:5432/timetracker POSTGRES_DB=timetracker POSTGRES_USER=timetracker POSTGRES_PASSWORD=timetracker POSTGRES_HOST=db # Session settings SESSION_COOKIE_SECURE=false SESSION_COOKIE_HTTPONLY=true PERMANENT_SESSION_LIFETIME=86400 # Application settings TZ=Europe/Rome CURRENCY=EUR ROUNDING_MINUTES=1 SINGLE_ACTIVE_TIMER=true IDLE_TIMEOUT_MINUTES=30 # User management ALLOW_SELF_REGISTER=true ADMIN_USERNAMES=admin # Authentication # Options: local | oidc | both AUTH_METHOD=local # OIDC (used when AUTH_METHOD=oidc or both) # OIDC_ISSUER=https://login.microsoftonline.com//v2.0 # OIDC_CLIENT_ID= # OIDC_CLIENT_SECRET= # OIDC_REDIRECT_URI=https://yourapp.example.com/auth/oidc/callback # OIDC_SCOPES=openid profile email # OIDC_USERNAME_CLAIM=preferred_username # OIDC_FULL_NAME_CLAIM=name # OIDC_EMAIL_CLAIM=email # OIDC_GROUPS_CLAIM=groups # OIDC_ADMIN_GROUP= # OIDC_ADMIN_EMAILS= # Optional: RP-Initiated Logout. Only set if your provider supports end_session_endpoint. # If unset, logout will be local only (recommended for providers like Authelia). # If set, TimeTracker will redirect to the provider's logout endpoint. # OIDC_POST_LOGOUT_REDIRECT_URI=https://yourapp.example.com/ # Backup settings BACKUP_RETENTION_DAYS=30 BACKUP_TIME=02:00 # File upload settings MAX_CONTENT_LENGTH=16777216 UPLOAD_FOLDER=/data/uploads # CSRF protection # IMPORTANT: Keep CSRF enabled in production for security # Only disable for development/testing if needed WTF_CSRF_ENABLED=true WTF_CSRF_TIME_LIMIT=3600 # CSRF SSL Strict Mode # Set to false if accessing via HTTP (localhost or IP address) # Set to true only when using HTTPS in production WTF_CSRF_SSL_STRICT=false # CSRF Cookie Settings # Only set these if you need to access the app via IP address or have cookie issues # CSRF_COOKIE_SECURE=false # Set to false for HTTP access # CSRF_COOKIE_SAMESITE=Lax # Options: Strict, Lax, None # CSRF_COOKIE_DOMAIN= # Leave empty for single domain, set for subdomains # Session Cookie Settings for IP Address Access # If accessing via IP address (e.g., 192.168.1.100), use these settings: # SESSION_COOKIE_SAMESITE=Lax # Change to 'None' only if needed for cross-site # SESSION_COOKIE_SECURE=false # Must be false for HTTP # TROUBLESHOOTING CSRF issues ("CSRF token missing or invalid" errors): # 1. SECRET_KEY changed? All CSRF tokens become invalid when SECRET_KEY changes # 2. Cookies blocked? Check browser settings and allow cookies from your domain # 3. Behind a proxy? Ensure proxy forwards cookies and doesn't strip them # 4. Token expired? Increase WTF_CSRF_TIME_LIMIT (in seconds) # 5. Multiple app instances? All must use the SAME SECRET_KEY # 6. Clock skew? Ensure server time is synchronized (use NTP) # 7. Accessing via IP? Set WTF_CSRF_SSL_STRICT=false and SESSION_COOKIE_SECURE=false # 8. Still broken? Try: docker-compose restart app # 9. For testing only: Set WTF_CSRF_ENABLED=false (NOT for production!) # See docs/CSRF_CONFIGURATION.md for detailed troubleshooting # Logging LOG_LEVEL=INFO LOG_FILE=/data/logs/timetracker.log # Analytics and Monitoring # All analytics features are optional and disabled by default # Sentry Error Monitoring (optional) # Get your DSN from https://sentry.io/settings/projects/ # SENTRY_DSN= # SENTRY_TRACES_RATE=0.0 # PostHog Product Analytics (optional) # Get your API key from https://app.posthog.com/project/settings # POSTHOG_API_KEY=phc_DDrseL1KJhVn4wKj12fVc7ryhHiaxJ4CAbgUpzC1354 # POSTHOG_HOST=https://us.i.posthog.com # Telemetry (optional, opt-in, anonymous) # Sends anonymous installation data via PostHog (version, hashed fingerprint) # Requires POSTHOG_API_KEY to be set # Default: false (disabled) # See docs/privacy.md for details # ENABLE_TELEMETRY=true # TELE_SALT=8f4a7b2e9c1d6f3a5e8b4c7d2a9f6e3b1c8d5a7f2e9b4c6d3a8f5e1b7c4d9a2f # APP_VERSION= # Automatically read from setup.py, override only if needed