// package config handles server configuration from environment variables. package config import ( "fmt" "os" "strconv" ) // Config holds all server configuration. type Config struct { // HTTP Port int `json:"port"` // Database DatabaseURL string `json:"database_url"` // Storage CASDir string `json:"cas_dir"` // Content-Addressable Storage root SkinsDir string `json:"skins_dir"` // Uploaded skins // Auth JWTSecret string `json:"jwt_secret"` CIsecret string `json:"ci_secret"` // Token for CI/CD launcher release endpoint // Public BaseURL string `json:"base_url"` // External URL for CDN links } // Load reads configuration from environment variables with sensible defaults. func Load() (*Config, error) { port, err := strconv.Atoi(getEnv("SERVER_PORT", "8080")) if err != nil { return nil, fmt.Errorf("invalid SERVER_PORT: %w", err) } cfg := &Config{ Port: port, DatabaseURL: getEnv("DATABASE_URL", ""), CASDir: getEnv("CAS_DIR", "/var/www/cdn/files"), SkinsDir: getEnv("SKINS_DIR", "/var/www/cdn/skins"), JWTSecret: getEnv("JWT_SECRET", ""), CIsecret: getEnv("CI_SECRET", ""), BaseURL: getEnv("BASE_URL", "https://minecraft.mrixs.me"), } if cfg.DatabaseURL == "" { return nil, fmt.Errorf("DATABASE_URL is required") } if cfg.JWTSecret == "" { return nil, fmt.Errorf("JWT_SECRET is required") } return cfg, nil } func getEnv(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback }