Configuration Guide
Overview
Weber uses JSON-based configuration files to manage settings across different environments. This approach allows you to easily customize behavior for development, testing, and production environments.
Configuration Files
Configuration files are stored in the config/ directory:
config/
├── dev.json # Development environment
├── test.json # Testing environment
└── prod.json # Production environment
Selecting Environment
Set the environment using the WEBER_ENV variable:
# Development
export WEBER_ENV=dev
# Production
export WEBER_ENV=prod
# Testing
export WEBER_ENV=test
Configuration Structure
Complete Example
{
"server": {
"port": 8080,
"host": "localhost",
"debug": true,
"read_timeout": 30,
"write_timeout": 30
},
"database": {
"driver": "postgres",
"host": "localhost",
"port": 5432,
"name": "weber_db",
"user": "weber",
"password": "password",
"ssl_mode": "disable",
"max_open_conns": 25,
"max_idle_conns": 5
},
"cache": {
"enabled": true,
"driver": "memory",
"ttl": 3600,
"max_size": 100
},
"logging": {
"level": "debug",
"output": "stdout",
"file": "logs/app.log",
"max_size": 100,
"max_backups": 3,
"max_age": 28
},
"templates": {
"path": "./webroot",
"cache": true,
"reload": false
},
"static": {
"path": "./webroot/static",
"url_prefix": "/static",
"max_age": 31536000
},
"api": {
"news_endpoint": "https://api.example.com/news",
"football_endpoint": "https://api.example.com/football",
"api_key": "your-api-key",
"timeout": 10,
"retry_attempts": 3
},
"cors": {
"enabled": true,
"allowed_origins": ["http://localhost:3000"],
"allowed_methods": ["GET", "POST", "PUT", "DELETE"],
"allowed_headers": ["Content-Type", "Authorization"],
"max_age": 86400
},
"session": {
"secret": "change-this-secret-key",
"cookie_name": "weber_session",
"max_age": 86400,
"secure": false,
"http_only": true
},
"oauth": {
"google": {
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"redirect_url": "http://localhost:8080/auth/google/callback"
}
}
}
Server Configuration
Development (dev.json)
{
"server": {
"port": 8080,
"host": "localhost",
"debug": true,
"read_timeout": 30,
"write_timeout": 30
}
}
Production (prod.json)
{
"server": {
"port": 80,
"host": "0.0.0.0",
"debug": false,
"read_timeout": 15,
"write_timeout": 15
}
}
Configuration Options
- port - Server port (default: 8080)
- host - Server host (default: localhost)
- debug - Enable debug mode (default: false)
- read_timeout - HTTP read timeout in seconds
- write_timeout - HTTP write timeout in seconds
Database Configuration
{
"database": {
"driver": "postgres",
"host": "localhost",
"port": 5432,
"name": "weber_db",
"user": "weber",
"password": "password",
"ssl_mode": "disable",
"max_open_conns": 25,
"max_idle_conns": 5,
"conn_max_lifetime": 300
}
}
Options
- driver - Database driver (postgres, mysql, sqlite)
- host - Database host
- port - Database port
- name - Database name
- user - Database user
- password - Database password
- ssl_mode - SSL mode (disable, require, verify-full)
- max_open_conns - Maximum open connections
- max_idle_conns - Maximum idle connections
- conn_max_lifetime - Connection max lifetime in seconds
Cache Configuration
{
"cache": {
"enabled": true,
"driver": "memory",
"ttl": 3600,
"max_size": 100,
"redis": {
"host": "localhost",
"port": 6379,
"password": "",
"db": 0
}
}
}
Cache Drivers
- memory - In-memory cache (default)
- redis - Redis cache
- file - File-based cache
Logging Configuration
{
"logging": {
"level": "debug",
"output": "stdout",
"file": "logs/app.log",
"format": "json",
"max_size": 100,
"max_backups": 3,
"max_age": 28,
"compress": true
}
}
Log Levels
- debug - All messages including debug
- info - Informational messages and above
- warn - Warning messages and above
- error - Error messages only
Output Options
- stdout - Console output
- file - File output
- both - Both console and file
Template Configuration
{
"templates": {
"path": "./webroot",
"cache": true,
"reload": false,
"extensions": [".html", ".tmpl"],
"delimiters": {
"left": "{{",
"right": "}}"
}
}
}
Options
- path - Template directory path
- cache - Enable template caching
- reload - Auto-reload templates on change (dev only)
- extensions - Template file extensions
API Configuration
{
"api": {
"news_endpoint": "https://api.example.com/news",
"football_endpoint": "https://api.example.com/football",
"api_key": "your-api-key",
"timeout": 10,
"retry_attempts": 3,
"retry_delay": 1,
"rate_limit": 100,
"rate_limit_window": 60
}
}
External API Settings
- endpoint - API endpoint URL
- api_key - API authentication key
- timeout - Request timeout in seconds
- retry_attempts - Number of retry attempts
- retry_delay - Delay between retries in seconds
CORS Configuration
{
"cors": {
"enabled": true,
"allowed_origins": [
"http://localhost:3000",
"https://example.com"
],
"allowed_methods": [
"GET",
"POST",
"PUT",
"DELETE",
"OPTIONS"
],
"allowed_headers": [
"Content-Type",
"Authorization",
"X-Requested-With"
],
"exposed_headers": [
"X-Total-Count"
],
"allow_credentials": true,
"max_age": 86400
}
}
Session Configuration
{
"session": {
"secret": "change-this-secret-key-in-production",
"cookie_name": "weber_session",
"max_age": 86400,
"secure": false,
"http_only": true,
"same_site": "lax",
"domain": "",
"path": "/"
}
}
Security Settings
- secret - Session encryption key (change in production!)
- secure - Send cookie only over HTTPS
- http_only - Prevent JavaScript access to cookie
- same_site - SameSite cookie attribute (strict, lax, none)
OAuth Configuration
{
"oauth": {
"google": {
"enabled": true,
"client_id": "your-google-client-id",
"client_secret": "your-google-client-secret",
"redirect_url": "http://localhost:8080/auth/google/callback",
"scopes": ["email", "profile"]
},
"github": {
"enabled": false,
"client_id": "your-github-client-id",
"client_secret": "your-github-client-secret",
"redirect_url": "http://localhost:8080/auth/github/callback"
}
}
}
Loading Configuration
In Code
import "weber/backend/app/config"
func main() {
// Load configuration
cfg, err := config.Load()
if err != nil {
log.Fatal(err)
}
// Access configuration
port := cfg.Server.Port
dbHost := cfg.Database.Host
debugMode := cfg.Server.Debug
// Use configuration
log.Printf("Starting server on port %d", port)
}
Configuration Struct
type Config struct {
Server ServerConfig
Database DatabaseConfig
Cache CacheConfig
Logging LoggingConfig
Templates TemplatesConfig
API APIConfig
CORS CORSConfig
Session SessionConfig
OAuth OAuthConfig
}
// Access nested values
timeout := cfg.API.Timeout
logLevel := cfg.Logging.Level
Environment Variables
Override configuration with environment variables:
# Override server port
export WEBER_PORT=3000
# Override debug mode
export WEBER_DEBUG=true
# Override database host
export WEBER_DB_HOST=db.example.com
# Override API key
export WEBER_API_KEY=secret-key
Priority Order
- Environment variables (highest priority)
- Configuration file
- Default values (lowest priority)
Environment-Specific Settings
Development
{
"server": {
"debug": true
},
"logging": {
"level": "debug",
"output": "stdout"
},
"templates": {
"cache": false,
"reload": true
},
"cache": {
"ttl": 60
}
}
Production
{
"server": {
"debug": false
},
"logging": {
"level": "info",
"output": "file",
"file": "/var/log/weber/app.log"
},
"templates": {
"cache": true,
"reload": false
},
"cache": {
"ttl": 3600,
"driver": "redis"
},
"session": {
"secure": true
}
}
Validation
Validate configuration on startup:
func ValidateConfig(cfg *Config) error {
if cfg.Server.Port < 1 || cfg.Server.Port > 65535 {
return errors.New("invalid port number")
}
if cfg.Session.Secret == "change-this-secret-key" {
return errors.New("please change session secret")
}
if cfg.Server.Debug && cfg.Logging.Level != "debug" {
log.Warn("Debug mode enabled but log level is not debug")
}
return nil
}
Secrets Management
Using Environment Variables
# .env file (don't commit to git!)
WEBER_DB_PASSWORD=secret-password
WEBER_API_KEY=secret-api-key
WEBER_SESSION_SECRET=secret-session-key
WEBER_OAUTH_CLIENT_SECRET=oauth-secret
Using Secret Files
# Store secrets in separate files
/run/secrets/db_password
/run/secrets/api_key
# Load in application
dbPassword, _ := ioutil.ReadFile("/run/secrets/db_password")
cfg.Database.Password = string(dbPassword)
Using Key Management Services
Integrate with services like AWS Secrets Manager, HashiCorp Vault, etc.
Best Practices
- Never commit secrets - Use environment variables or secret management
- Use different configs per environment - dev, test, prod
- Validate configuration - Check values on startup
- Document settings - Explain what each setting does
- Use sensible defaults - Provide default values when possible
- Environment variables for secrets - Never hardcode sensitive data
- Version control config structure - But not sensitive values
- Test configuration loading - Ensure configs load correctly
Example: Configuration Setup
// main.go
package main
import (
"log"
"weber/backend/app"
"weber/backend/app/config"
"weber/backend/route"
)
func main() {
// Load configuration
cfg, err := config.Load()
if err != nil {
log.Fatal("Failed to load config:", err)
}
// Validate configuration
if err := config.Validate(cfg); err != nil {
log.Fatal("Invalid config:", err)
}
// Create app with config
webApp := app.NewWithConfig(cfg)
// Setup routes
route.Setup(webApp)
// Start server
addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
log.Printf("Starting server on %s (debug: %v)", addr, cfg.Server.Debug)
if err := webApp.Run(addr); err != nil {
log.Fatal("Server error:", err)
}
}