# TankStopp Configuration Documentation ## Overview TankStopp uses [Viper](https://github.com/spf13/viper) for configuration management, providing a flexible and powerful way to configure the application using: - **Configuration files** (YAML, JSON, TOML, etc.) - **Environment variables** - **Command-line flags** (future feature) - **Default values** This system allows for easy deployment across different environments while maintaining security and flexibility. ## Configuration Precedence Configuration values are loaded in the following order (highest to lowest priority): 1. **Environment variables** (highest priority) 2. **Configuration files** 3. **Default values** (lowest priority) This means environment variables will always override config file values, providing a secure way to override sensitive settings in production. ## Configuration File Locations The application searches for configuration files in the following locations (in order): 1. **Explicit path**: If `TANKSTOPP_CONFIG_PATH` environment variable is set 2. **Current directory**: `./config.yaml` 3. **Config subdirectory**: `./config/config.yaml` 4. **User home directory**: `$HOME/.tankstopp/config.yaml` 5. **System directory**: `/etc/tankstopp/config.yaml` ### Environment-Specific Configuration You can use environment-specific configuration files: - `config.development.yaml` - Development environment - `config.production.yaml` - Production environment - `config.test.yaml` - Test environment Set the `TANKSTOPP_ENV` or `ENV` environment variable to automatically load the appropriate config file. ## Supported File Formats - **YAML** (recommended): `config.yaml` - **JSON**: `config.json` - **TOML**: `config.toml` - **Properties**: `config.properties` ## Configuration Structure ### Complete Configuration Example ```yaml # Server Configuration server: host: "localhost" port: 8081 read_timeout: 30s write_timeout: 30s idle_timeout: 120s shutdown_timeout: 10s # Database Configuration database: path: "fuel_stops.db" connection_pool: max_idle_connections: 10 max_open_connections: 100 connection_max_lifetime: "1h" connection_max_idle_time: "30m" logging: level: "warn" # silent, error, warn, info slow_query_threshold: "200ms" debug: false migration: auto_migrate: true drop_tables_first: false create_batch_size: 1000 performance: prepare_statements: true disable_foreign_key_check: false ignore_relationships_when_migrating: false query_fields: true dry_run: false create_in_batches: 100 # Application Settings app: name: "TankStopp" version: "1.0.0" environment: "development" # development, production, test debug: true # Security Settings security: session: timeout: "24h" cookie_name: "tankstopp_session" secure_cookies: false http_only: true password: min_length: 8 require_uppercase: true require_lowercase: true require_numbers: true require_special_chars: false # Logging Configuration logging: level: "info" # debug, info, warn, error format: "text" # text, json output: "stdout" # stdout, stderr, file file_path: "logs/tankstopp.log" rotation: enabled: false max_size: "100MB" max_age: "30d" max_backups: 5 # External Services external_services: overpass_api: url: "https://overpass-api.de/api/interpreter" timeout: "30s" max_retries: 3 search_radius: 5000 # Feature Flags features: fuel_station_search: true vehicle_management: true statistics_dashboard: true data_export: true api_endpoints: true # Default Values defaults: currency: "EUR" fuel_type: "Super E5" distance_unit: "km" volume_unit: "liters" ``` ## Environment Variables All configuration options can be overridden using environment variables with the `TANKSTOPP_` prefix: ### Format Convention Convert the YAML path to an environment variable by: 1. Adding `TANKSTOPP_` prefix 2. Converting to uppercase 3. Replacing dots (.) with underscores (_) ### Examples | YAML Path | Environment Variable | |-----------|---------------------| | `server.port` | `TANKSTOPP_SERVER_PORT` | | `database.path` | `TANKSTOPP_DATABASE_PATH` | | `database.connection_pool.max_idle_connections` | `TANKSTOPP_DATABASE_CONNECTION_POOL_MAX_IDLE_CONNECTIONS` | | `app.debug` | `TANKSTOPP_APP_DEBUG` | | `security.session.timeout` | `TANKSTOPP_SECURITY_SESSION_TIMEOUT` | ### Legacy Environment Variables For backward compatibility, these legacy environment variables are still supported: | Legacy Variable | New Variable | Description | |----------------|--------------|-------------| | `DB_PATH` | `TANKSTOPP_DATABASE_PATH` | Database file path | | `DB_MAX_IDLE_CONNS` | `TANKSTOPP_DATABASE_CONNECTION_POOL_MAX_IDLE_CONNECTIONS` | Max idle connections | | `DB_MAX_OPEN_CONNS` | `TANKSTOPP_DATABASE_CONNECTION_POOL_MAX_OPEN_CONNECTIONS` | Max open connections | | `DB_DEBUG` | `TANKSTOPP_DATABASE_LOGGING_DEBUG` | Debug mode | | `ENV` | `TANKSTOPP_APP_ENVIRONMENT` | Application environment | ## Configuration Options Reference ### Server Configuration | Option | Type | Default | Description | |--------|------|---------|-------------| | `server.host` | string | `"localhost"` | Server bind address | | `server.port` | int | `8081` | Server port | | `server.read_timeout` | duration | `"30s"` | HTTP read timeout | | `server.write_timeout` | duration | `"30s"` | HTTP write timeout | | `server.idle_timeout` | duration | `"120s"` | HTTP idle timeout | | `server.shutdown_timeout` | duration | `"10s"` | Graceful shutdown timeout | ### Database Configuration | Option | Type | Default | Description | |--------|------|---------|-------------| | `database.path` | string | `"fuel_stops.db"` | SQLite database file path | | `database.connection_pool.max_idle_connections` | int | `10` | Maximum idle connections | | `database.connection_pool.max_open_connections` | int | `100` | Maximum open connections | | `database.connection_pool.connection_max_lifetime` | duration | `"1h"` | Connection max lifetime | | `database.connection_pool.connection_max_idle_time` | duration | `"30m"` | Connection max idle time | | `database.logging.level` | string | `"warn"` | Log level: silent, error, warn, info | | `database.logging.slow_query_threshold` | duration | `"200ms"` | Slow query threshold | | `database.logging.debug` | bool | `false` | Enable debug logging | | `database.migration.auto_migrate` | bool | `true` | Auto-run migrations | | `database.migration.drop_tables_first` | bool | `false` | Drop tables before migration | | `database.migration.create_batch_size` | int | `1000` | Batch size for bulk operations | ### Application Configuration | Option | Type | Default | Description | |--------|------|---------|-------------| | `app.name` | string | `"TankStopp"` | Application name | | `app.version` | string | `"1.0.0"` | Application version | | `app.environment` | string | `"development"` | Environment: development, production, test | | `app.debug` | bool | `true` | Enable debug mode | ### Security Configuration | Option | Type | Default | Description | |--------|------|---------|-------------| | `security.session.timeout` | duration | `"24h"` | Session timeout | | `security.session.cookie_name` | string | `"tankstopp_session"` | Session cookie name | | `security.session.secure_cookies` | bool | `false` | Require HTTPS for cookies | | `security.session.http_only` | bool | `true` | HTTP-only cookies | | `security.password.min_length` | int | `8` | Minimum password length | | `security.password.require_uppercase` | bool | `true` | Require uppercase letters | | `security.password.require_lowercase` | bool | `true` | Require lowercase letters | | `security.password.require_numbers` | bool | `true` | Require numbers | | `security.password.require_special_chars` | bool | `false` | Require special characters | ## Environment-Specific Configurations ### Development Configuration ```yaml # config.development.yaml server: host: "localhost" port: 8081 database: path: "fuel_stops_dev.db" logging: level: "info" debug: true app: environment: "development" debug: true security: session: timeout: "8h" secure_cookies: false password: min_length: 6 require_uppercase: false require_special_chars: false logging: level: "debug" format: "text" output: "stdout" ``` ### Production Configuration ```yaml # config.production.yaml server: host: "0.0.0.0" port: 8080 database: path: "/var/lib/tankstopp/fuel_stops.db" logging: level: "error" debug: false migration: auto_migrate: false app: environment: "production" debug: false security: session: timeout: "24h" secure_cookies: true password: min_length: 12 require_special_chars: true logging: level: "info" format: "json" output: "file" file_path: "/var/log/tankstopp/application.log" rotation: enabled: true max_size: "500MB" max_age: "90d" ``` ## Migration from Environment Variables If you're currently using environment variables only, you can migrate to config files: ### Step 1: Create Base Configuration Create a `config.yaml` file with your current settings: ```yaml server: port: 8081 database: path: "fuel_stops.db" app: environment: "development" ``` ### Step 2: Environment-Specific Overrides Keep sensitive or environment-specific values as environment variables: ```bash # Production overrides export TANKSTOPP_DATABASE_PATH="/var/lib/tankstopp/fuel_stops.db" export TANKSTOPP_APP_ENVIRONMENT="production" export TANKSTOPP_APP_DEBUG="false" ``` ### Step 3: Gradual Migration You can migrate gradually since environment variables take precedence over config files. ## Docker Configuration ### Using Configuration Files ```dockerfile # Copy config files COPY config.production.yaml /app/config.yaml # Set environment for config selection ENV TANKSTOPP_ENV=production ``` ### Using Environment Variables ```dockerfile # Database configuration ENV TANKSTOPP_DATABASE_PATH=/var/lib/tankstopp/fuel_stops.db ENV TANKSTOPP_APP_ENVIRONMENT=production ENV TANKSTOPP_APP_DEBUG=false # Server configuration ENV TANKSTOPP_SERVER_HOST=0.0.0.0 ENV TANKSTOPP_SERVER_PORT=8080 ``` ### Docker Compose Example ```yaml version: '3.8' services: tankstopp: build: . ports: - "8080:8080" environment: - TANKSTOPP_DATABASE_PATH=/data/fuel_stops.db - TANKSTOPP_APP_ENVIRONMENT=production - TANKSTOPP_APP_DEBUG=false volumes: - ./data:/data - ./config.production.yaml:/app/config.yaml ``` ## Kubernetes Configuration ### ConfigMap Example ```yaml apiVersion: v1 kind: ConfigMap metadata: name: tankstopp-config data: config.yaml: | server: host: "0.0.0.0" port: 8080 database: path: "/data/fuel_stops.db" app: environment: "production" debug: false ``` ### Secret Example ```yaml apiVersion: v1 kind: Secret metadata: name: tankstopp-secrets type: Opaque stringData: DATABASE_PATH: "/secure/fuel_stops.db" ``` ## Validation and Debugging ### Configuration Validation The application validates configuration on startup. Common validation errors: - **Invalid port number**: Must be between 1-65535 - **Empty database path**: Database path cannot be empty - **Invalid environment**: Must be development, production, or test - **Invalid log level**: Must be debug, info, warn, or error ### Debugging Configuration Enable debug logging to see configuration loading: ```bash export TANKSTOPP_APP_DEBUG=true export TANKSTOPP_LOGGING_LEVEL=debug ``` The application will log: - Which config files were found and loaded - Which environment variables are being used - Final merged configuration (without sensitive values) ### Testing Configuration You can test configuration without starting the full application: ```bash # Test with specific config file TANKSTOPP_CONFIG_PATH=config.production.yaml ./tankstopp --validate-config # Test with environment variables TANKSTOPP_APP_DEBUG=true ./tankstopp --validate-config ``` ## Security Best Practices ### 1. File Permissions Protect configuration files containing sensitive data: ```bash chmod 600 config.production.yaml chown tankstopp:tankstopp config.production.yaml ``` ### 2. Environment Variables for Secrets Use environment variables for sensitive values: ```bash # Don't put secrets in config files export TANKSTOPP_DATABASE_PATH="/secure/path/fuel_stops.db" export TANKSTOPP_SECURITY_SESSION_COOKIE_NAME="secure_session_name" ``` ### 3. Production Settings Ensure production-safe defaults: ```yaml app: environment: "production" debug: false security: session: secure_cookies: true http_only: true logging: level: "info" # Don't use debug in production ``` ## Troubleshooting ### Common Issues **1. Configuration file not found** ``` Warning: Failed to load config file 'config.yaml': Config File "config" Not Found ``` - Check file exists in search paths - Verify file permissions - Check `TANKSTOPP_CONFIG_PATH` environment variable **2. Invalid YAML syntax** ``` Error reading config file: yaml: line 10: mapping values are not allowed in this context ``` - Validate YAML syntax using an online validator - Check indentation (use spaces, not tabs) - Ensure proper quoting of string values **3. Environment variable not working** ``` Configuration not being overridden by environment variable ``` - Verify variable name format: `TANKSTOPP_` prefix + uppercase + underscores - Check variable is exported: `export TANKSTOPP_SERVER_PORT=8080` - Verify no typos in variable name **4. Database connection issues** ``` Failed to connect to database: unable to open database file ``` - Check database path exists and is writable - Verify file permissions - Ensure directory exists ### Getting Help 1. **Enable debug logging**: Set `TANKSTOPP_APP_DEBUG=true` 2. **Check configuration loading**: Look for config-related log messages 3. **Validate configuration**: Use `--validate-config` flag 4. **Test minimal config**: Start with basic configuration and add options gradually ## Advanced Usage ### Custom Configuration Paths ```bash # Use custom config file export TANKSTOPP_CONFIG_PATH=/etc/myapp/custom-config.yaml # Use config directory export TANKSTOPP_CONFIG_PATH=/etc/myapp/ ``` ### Multiple Configuration Files You can split configuration across multiple files: ```yaml # base.yaml server: host: "localhost" database: path: "fuel_stops.db" ``` ```yaml # security.yaml security: session: timeout: "24h" ``` ### Configuration Templating Use environment variable substitution in config files: ```yaml database: path: "${DATABASE_PATH:-fuel_stops.db}" server: port: ${PORT:-8081} ``` This documentation provides comprehensive coverage of the TankStopp configuration system. For additional questions or advanced use cases, refer to the [Viper documentation](https://github.com/spf13/viper) or check the application source code.