# Configuration This package provides configuration management for the relay with support for YAML files and environment variable overrides. ## Overview Configuration can be loaded from: 1. **YAML file** - Primary configuration source 2. **Environment variables** - Override file values 3. **Defaults** - Sensible defaults if not specified ## Usage ### Load from File ```go import "northwest.io/muxstr/internal/config" // Load configuration cfg, err := config.Load("config.yaml") if err != nil { log.Fatal(err) } // Use configuration fmt.Printf("gRPC listening on %s\n", cfg.Server.GrpcAddr) ``` ### Load with Environment Overrides ```bash # Set environment variables export MUXSTR_SERVER_GRPC_ADDR=":50051" export MUXSTR_AUTH_REQUIRED=true export MUXSTR_RATE_LIMIT_DEFAULT_RPS=100 # Run relay ./relay -config config.yaml ``` Environment variables use the format: `MUXSTR_
_` ### Use Defaults ```go // Get default configuration cfg := config.Default() ``` ## Configuration File Format ### Complete Example ```yaml # Server configuration server: # gRPC server address grpc_addr: ":50051" # HTTP server address (for Connect and WebSocket) http_addr: ":8080" # Public URL for reverse proxy deployments (optional) # Example: "relay.example.com" public_url: "" # Read timeout for requests (optional) read_timeout: "30s" # Write timeout for responses (optional) write_timeout: "30s" # Database configuration database: # Path to SQLite database file path: "relay.db" # Maximum number of open connections max_connections: 10 # Connection max lifetime max_lifetime: "1h" # Authentication configuration auth: # Enable authentication enabled: false # Require authentication for all requests # If false, authentication is optional (pubkey available if provided) required: false # Timestamp window in seconds for replay protection timestamp_window: 60 # Allowed pubkeys (optional, whitelist) # If empty, all valid signatures are accepted allowed_pubkeys: [] # Skip authentication for these methods skip_methods: - "/grpc.health.v1.Health/Check" # Rate limiting configuration rate_limit: # Enable rate limiting enabled: false # Default rate limit (requests per second) default_rps: 10 # Default burst size (token bucket capacity) default_burst: 20 # Rate limit for unauthenticated users (per IP) ip_rps: 5 ip_burst: 10 # Method-specific limits methods: "/nostr.v1.NostrRelay/PublishEvent": rps: 2 burst: 5 "/nostr.v1.NostrRelay/Subscribe": rps: 1 burst: 3 # User-specific limits (VIP/premium users) users: "vip-pubkey-here": rps: 100 burst: 200 # Skip rate limiting for these methods skip_methods: - "/grpc.health.v1.Health/Check" # Skip rate limiting for these pubkeys (admins) skip_users: [] # Cleanup interval for idle limiters cleanup_interval: "5m" # Max idle time before limiter is removed max_idle_time: "10m" # Metrics configuration metrics: # Enable Prometheus metrics enabled: true # Metrics HTTP server address addr: ":9090" # Metrics path path: "/metrics" # Namespace for metrics namespace: "muxstr" # Subsystem for metrics subsystem: "relay" # Logging configuration logging: # Log level: debug, info, warn, error level: "info" # Log format: json, text format: "json" # Output: stdout, stderr, or file path output: "stdout" # Storage configuration storage: # Enable automatic compaction auto_compact: true # Compact interval compact_interval: "24h" # Maximum event age (0 = unlimited) max_event_age: "0" ``` ### Minimal Example ```yaml server: grpc_addr: ":50051" http_addr: ":8080" database: path: "relay.db" metrics: enabled: true addr: ":9090" ``` ## Environment Variables All configuration values can be overridden with environment variables using the pattern: ``` MUXSTR_
__=value ``` Examples: | Config Path | Environment Variable | |-------------|---------------------| | `server.grpc_addr` | `MUXSTR_SERVER_GRPC_ADDR` | | `database.path` | `MUXSTR_DATABASE_PATH` | | `auth.required` | `MUXSTR_AUTH_REQUIRED` | | `rate_limit.default_rps` | `MUXSTR_RATE_LIMIT_DEFAULT_RPS` | | `metrics.enabled` | `MUXSTR_METRICS_ENABLED` | Complex types: ```bash # Lists (comma-separated) export MUXSTR_AUTH_ALLOWED_PUBKEYS="pubkey1,pubkey2,pubkey3" # Durations export MUXSTR_SERVER_READ_TIMEOUT="30s" export MUXSTR_DATABASE_MAX_LIFETIME="1h" # Booleans export MUXSTR_AUTH_ENABLED=true export MUXSTR_METRICS_ENABLED=false ``` ## Validation Configuration is validated on load: ```go cfg, err := config.Load("config.yaml") if err != nil { // Validation errors include detailed messages log.Fatalf("Invalid configuration: %v", err) } ``` Validation checks: - Required fields are present - Addresses are valid (host:port format) - File paths are accessible - Numeric values are in valid ranges - Durations are parseable ## Default Values If not specified, the following defaults are used: ```go Server: GrpcAddr: ":50051" HttpAddr: ":8080" ReadTimeout: 30s WriteTimeout: 30s Database: Path: "relay.db" MaxConnections: 10 MaxLifetime: 1h Auth: Enabled: false Required: false TimestampWindow: 60 RateLimit: Enabled: false DefaultRPS: 10 DefaultBurst: 20 IPRPS: 5 IPBurst: 10 CleanupInterval: 5m MaxIdleTime: 10m Metrics: Enabled: true Addr: ":9090" Path: "/metrics" Namespace: "muxstr" Subsystem: "relay" Logging: Level: "info" Format: "json" Output: "stdout" ``` ## Configuration Precedence Values are loaded in this order (later overrides earlier): 1. **Defaults** - Built-in default values 2. **Config file** - Values from YAML file 3. **Environment variables** - OS environment overrides Example: ```yaml # config.yaml server: grpc_addr: ":50051" ``` ```bash # Environment override export MUXSTR_SERVER_GRPC_ADDR=":9000" # Result: gRPC listens on :9000 (env var wins) ``` ## Reloading Configuration Configuration can be reloaded without restart (future feature): ```go // Watch for changes watcher, err := config.Watch("config.yaml") if err != nil { log.Fatal(err) } for cfg := range watcher.Updates { // Apply new configuration updateServer(cfg) } ``` ## Best Practices 1. **Use config files for static settings**: Server addresses, paths, etc. 2. **Use env vars for deployment-specific settings**: Secrets, environment-specific URLs 3. **Keep secrets out of config files**: Use env vars or secret management 4. **Version control your config**: Check in config.yaml (without secrets) 5. **Document custom settings**: Add comments to config.yaml 6. **Validate in CI**: Run `relay -config config.yaml -validate` in CI pipeline 7. **Use different configs per environment**: `config.dev.yaml`, `config.prod.yaml` ## Example Configurations ### Development ```yaml server: grpc_addr: ":50051" http_addr: ":8080" database: path: "relay-dev.db" auth: enabled: false rate_limit: enabled: false metrics: enabled: true addr: ":9090" logging: level: "debug" format: "text" ``` ### Production ```yaml server: grpc_addr: ":50051" http_addr: ":8080" public_url: "relay.example.com" read_timeout: "30s" write_timeout: "30s" database: path: "/var/lib/muxstr/relay.db" max_connections: 50 auth: enabled: true required: false timestamp_window: 60 rate_limit: enabled: true default_rps: 10 default_burst: 20 methods: "/nostr.v1.NostrRelay/PublishEvent": rps: 2 burst: 5 metrics: enabled: true addr: ":9090" logging: level: "info" format: "json" output: "/var/log/muxstr/relay.log" ``` ### High-Performance ```yaml server: grpc_addr: ":50051" http_addr: ":8080" database: path: "/mnt/fast-ssd/relay.db" max_connections: 100 max_lifetime: "30m" auth: enabled: true required: true timestamp_window: 30 rate_limit: enabled: true default_rps: 100 default_burst: 200 metrics: enabled: true addr: ":9090" logging: level: "warn" format: "json" ```