Documentation

Configuration

Overview

The framework uses environment-based configuration with support for multiple environments and flexible configuration sources.

Environment Setup

Environment Variable

# Set environment
export ENV=dev          # Development
export ENV=prod         # Production
export ENV=test         # Testing

Configuration Files

config/envs/
├── dev.env           # Development settings
├── prod.env          # Production settings
└── test.env          # Test settings

Core Configuration

Application Settings

# Application
APP_NAME=MyApplication
APP_VERSION=1.0.0
APP_URL=http://localhost:8080

# Server
PORT=8080
HOST=localhost
READ_TIMEOUT=30s
WRITE_TIMEOUT=30s

Database Configuration

SQLite (Default)

# SQLite database
DB_DRIVER=sqlite3
DB_PATH=data/db.db
DB_MIGRATION_PATH=data/schema.sqlite.sql

PostgreSQL (Optional)

# PostgreSQL database
DB_DRIVER=postgres
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=postgres
DB_PASS=password
DB_SSLMODE=disable
DB_MIGRATION_PATH=data/schema.pg.sql

Development Settings

# Development
DEBUG=true
LOG_LEVEL=debug
HOT_RELOAD=true

# Air hot reloading
AIR_CONFIG=air.dev.toml

Production Settings

# Production
DEBUG=false
LOG_LEVEL=info
HOT_RELOAD=false

# Security
SESSION_SECRET=your-secret-key
JWT_SECRET=your-jwt-secret
CSRF_SECRET=your-csrf-secret

Configuration Loading

Loading Order

  1. Environment variables
  2. .env file in project root
  3. config/envs/{ENV}.env file
  4. Default values in code

Example Configuration Loading

// src/lib/config/config.go
package config

import (
    "os"
    "strconv"
    "time"
)

type Config struct {
    Environment string
    Port        int
    Database    DatabaseConfig
    Server      ServerConfig
    Security    SecurityConfig
}

type DatabaseConfig struct {
    Driver      string
    Path        string
    Host        string
    Port        int
    Name        string
    User        string
    Password    string
    SSLMode     string
}

func Load() *Config {
    return &Config{
        Environment: getEnv("ENV", "dev"),
        Port:        getEnvAsInt("PORT", 8080),
        Database: DatabaseConfig{
            Driver:   getEnv("DB_DRIVER", "sqlite3"),
            Path:     getEnv("DB_PATH", "data/db.db"),
            Host:     getEnv("DB_HOST", "localhost"),
            Port:     getEnvAsInt("DB_PORT", 5432),
            Name:     getEnv("DB_NAME", "myapp"),
            User:     getEnv("DB_USER", "postgres"),
            Password: getEnv("DB_PASS", ""),
            SSLMode:  getEnv("DB_SSLMODE", "disable"),
        },
        // ... other config
    }
}

func getEnv(key, defaultValue string) string {
    if value := os.Getenv(key); value != "" {
        return value
    }
    return defaultValue
}

func getEnvAsInt(key string, defaultValue int) int {
    if value := os.Getenv(key); value != "" {
        if intValue, err := strconv.Atoi(value); err == nil {
            return intValue
        }
    }
    return defaultValue
}

Environment-Specific Configuration

Development Environment

# config/envs/dev.env
ENV=dev
DEBUG=true
LOG_LEVEL=debug

# Database
DB_DRIVER=sqlite3
DB_PATH=data/dev.db

# Server
PORT=8080
HOT_RELOAD=true

# Frontend
CSS_WATCH=true
JS_WATCH=true

Production Environment

# config/envs/prod.env
ENV=prod
DEBUG=false
LOG_LEVEL=warn

# Database
DB_DRIVER=postgres
DB_HOST=prod-db-host
DB_NAME=myapp_prod
DB_USER=prod_user
DB_PASS=secure_password

# Server
PORT=8080
READ_TIMEOUT=60s
WRITE_TIMEOUT=60s

# Security
SESSION_SECRET=production-session-secret
JWT_SECRET=production-jwt-secret

# Performance
CACHE_ENABLED=true
GZIP_ENABLED=true

Testing Environment

# config/envs/test.env
ENV=test
DEBUG=true
LOG_LEVEL=error

# Test Database
DB_DRIVER=sqlite3
DB_PATH=:memory:

# Disable external services
DISABLE_EXTERNAL_APIS=true

Advanced Configuration

Feature Flags

# Feature flags
FEATURE_USER_REGISTRATION=true
FEATURE_EMAIL_NOTIFICATIONS=false
FEATURE_SEARCH_INDEXING=true
FEATURE_BACKGROUND_JOBS=true

External Services

# Email service
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password

# Cloud storage
AWS_REGION=us-west-2
AWS_BUCKET=your-bucket-name
AWS_ACCESS_KEY=your-access-key
AWS_SECRET_KEY=your-secret-key

# Redis (optional)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0

Logging Configuration

# Logging
LOG_LEVEL=info              # debug, info, warn, error
LOG_FORMAT=json             # json, text
LOG_OUTPUT=stdout           # stdout, stderr, file
LOG_FILE=logs/app.log       # when LOG_OUTPUT=file

Configuration in Code

Using Configuration

// In your application code
func NewUserHandler(config *config.Config) *UserHandler {
    return &UserHandler{
        config: config,
    }
}

func (h *UserHandler) someMethod() {
    if h.config.Environment == "prod" {
        // Production-specific logic
    }

    if h.config.Security.JWTSecret != "" {
        // JWT is configured
    }
}

Configuration Validation

func (c *Config) Validate() error {
    if c.Environment == "" {
        return errors.New("ENV is required")
    }

    if c.Environment == "prod" && c.Security.SessionSecret == "" {
        return errors.New("SESSION_SECRET is required in production")
    }

    if c.Database.Driver == "postgres" {
        if c.Database.Host == "" || c.Database.Name == "" {
            return errors.New("PostgreSQL configuration incomplete")
        }
    }

    return nil
}

Docker Configuration

Development Docker

# Use environment file
ENV_FILE=config/envs/dev.env

# Mount configuration
VOLUME ./config:/app/config

Production Docker

# Set environment variables
ENV ENV=prod
ENV PORT=8080
ENV DB_DRIVER=postgres

# Production-specific settings
ENV DEBUG=false
ENV LOG_LEVEL=info

Configuration Best Practices

Security

  • Never commit secrets to version control
  • Use environment variables for sensitive data
  • Rotate secrets regularly
  • Use different secrets per environment

Organization

  • Group related configuration together
  • Use consistent naming conventions
  • Document all configuration options
  • Provide sensible defaults

Environment Management

  • Keep environment-specific settings minimal
  • Use feature flags for conditional features
  • Validate configuration at startup
  • Log configuration errors clearly

Common Configuration Patterns

Database URL Pattern

func BuildDatabaseURL(config DatabaseConfig) string {
    if config.Driver == "postgres" {
        return fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s",
            config.User, config.Password, config.Host, config.Port,
            config.Name, config.SSLMode)
    }
    return config.Path // SQLite path
}

Conditional Features

func (app *App) configureFeatures() {
    if app.config.Features.UserRegistration {
        app.router.RegisterUserRoutes()
    }

    if app.config.Features.EmailNotifications {
        app.emailService = NewEmailService(app.config.SMTP)
    }
}

Troubleshooting

Configuration Issues

# Check environment
echo $ENV

# Verify configuration file exists
ls -la config/envs/

# Test configuration loading
./app --config-test

Common Problems

  1. Wrong environment - Check ENV variable
  2. Missing configuration file - Ensure file exists in config/envs/
  3. Database connection - Verify database settings
  4. Port conflicts - Check if port is already in use

LLM Configuration Notes

When working with configuration: - Always check ENV environment variable first - Configuration precedence: env vars > files > defaults - Validate required configuration at startup - Use type-safe configuration structures - Environment-specific files are in config/envs/ - Database configuration supports both SQLite and PostgreSQL