Skip to Content
DocumentationGuidesConfiguration

Configuration

Gofasta uses a config.yaml file at the project root as the central configuration source. Every setting can be overridden with environment variables, making it easy to configure different environments without changing files.

Loading Configuration

The github.com/gofastadev/gofasta/pkg/config package loads and parses configuration:

import "github.com/gofastadev/gofasta/pkg/config" cfg := config.LoadConfig("config.yaml")

LoadConfig reads the YAML file, then checks for environment variable overrides. The resulting config struct is passed to the DI container and used throughout the application.

Full config.yaml Reference

Here is the complete configuration file with all available sections and their defaults:

# Application settings app: name: myapp port: 8080 env: development # development, staging, production debug: true url: http://localhost:8080 # Database configuration database: driver: postgres # postgres, mysql, sqlite, sqlserver, clickhouse host: localhost port: 5432 name: myapp_db user: postgres password: postgres ssl_mode: disable max_open_conns: 25 max_idle_conns: 5 conn_max_lifetime: 5m # JWT authentication jwt: secret: change-me-in-production expiration: 24h refresh_expiration: 168h issuer: myapp # Redis (used for caching, sessions, and queue) redis: host: localhost port: 6379 password: "" db: 0 # Cache configuration cache: driver: memory # memory or redis ttl: 5m # Session configuration session: driver: cookie # cookie or redis secret: session-secret max_age: 86400 # Email configuration mail: driver: smtp # smtp, sendgrid, or brevo from_name: MyApp from_address: noreply@myapp.com smtp: host: smtp.mailtrap.io port: 587 username: "" password: "" encryption: tls sendgrid: api_key: "" brevo: api_key: "" # Queue configuration queue: driver: memory # memory or redis workers: 5 retry_attempts: 3 retry_delay: 30s # Storage configuration storage: driver: local # local, s3 local: path: ./uploads s3: bucket: myapp-uploads region: us-east-1 access_key: "" secret_key: "" # Observability observability: metrics: enabled: true path: /metrics tracing: enabled: false exporter: jaeger endpoint: http://localhost:14268/api/traces # Rate limiting rate_limit: enabled: true max: 100 window: 1m # CORS cors: allowed_origins: - http://localhost:3000 allowed_methods: - GET - POST - PUT - DELETE - OPTIONS allowed_headers: - Authorization - Content-Type max_age: 86400 # Logging log: level: info # debug, info, warn, error format: json # json or text # Feature flags features: graphql_playground: true swagger: true registration: true

Environment Variable Overrides

Every config value can be overridden with an environment variable. The prefix is always GOFASTA_, followed by the section and key in uppercase, joined with underscores:

GOFASTA_{SECTION}_{KEY}
Config PathEnvironment Variable
app.portGOFASTA_APP_PORT
app.envGOFASTA_APP_ENV
database.hostGOFASTA_DATABASE_HOST
database.passwordGOFASTA_DATABASE_PASSWORD
jwt.secretGOFASTA_JWT_SECRET
jwt.expirationGOFASTA_JWT_EXPIRATION
redis.hostGOFASTA_REDIS_HOST
redis.portGOFASTA_REDIS_PORT
mail.driverGOFASTA_MAIL_DRIVER
mail.sendgrid.api_keyGOFASTA_MAIL_SENDGRID_API_KEY

Environment variables always take precedence over config.yaml values.

Database Configuration

PostgreSQL (default)

database: driver: postgres host: localhost port: 5432 name: myapp_db user: postgres password: postgres ssl_mode: disable

MySQL

database: driver: mysql host: localhost port: 3306 name: myapp_db user: root password: root

SQLite

database: driver: sqlite name: ./data/myapp.db

SQL Server

database: driver: sqlserver host: localhost port: 1433 name: myapp_db user: sa password: YourStrong!Passw0rd

ClickHouse

database: driver: clickhouse host: localhost port: 9000 name: myapp_db user: default password: ""

Connection Pool Settings

Tune connection pool settings for production:

database: max_open_conns: 50 # Maximum number of open connections max_idle_conns: 10 # Maximum number of idle connections conn_max_lifetime: 10m # Maximum time a connection can be reused

JWT Configuration

jwt: secret: your-256-bit-secret expiration: 24h # Access token lifetime refresh_expiration: 168h # Refresh token lifetime (7 days) issuer: myapp # Token issuer claim

For production, always set the secret via environment variable:

GOFASTA_JWT_SECRET=$(openssl rand -hex 32)

Redis Configuration

Redis is used by the cache, session, and queue packages when configured with the redis driver:

redis: host: localhost port: 6379 password: "" db: 0

Multiple components can use the same Redis instance on different databases:

redis: host: localhost port: 6379 cache: driver: redis queue: driver: redis session: driver: redis

Feature Flags

Feature flags in config.yaml control optional functionality:

features: graphql_playground: true # Enable GraphQL Playground UI swagger: true # Enable Swagger documentation endpoint registration: true # Enable user registration endpoint

For more complex scenarios — user-targeted rollouts, percentage-based releases, A/B tests — the github.com/gofastadev/gofasta/pkg/featureflag package wraps the OpenFeature Go SDK  so you can plug in whichever flag backend you prefer (in-memory, Flagd , LaunchDarkly , go-feature-flag , or a custom provider). The simplest production-ready setup is the in-memory provider:

import ( "github.com/gofastadev/gofasta/pkg/featureflag" "github.com/open-feature/go-sdk/openfeature/memprovider" ) flags := map[string]memprovider.InMemoryFlag{ "registration": { Key: "registration", State: memprovider.Enabled, DefaultVariant: "on", Variants: map[string]any{"on": true, "off": false}, }, } ff, err := featureflag.NewInMemoryService(flags, logger) if err != nil { return err } defer ff.Close() if ff.IsEnabled(ctx, "registration", user.ID.String(), map[string]any{"plan": user.Plan}) { RegisterAuthRoutes(router, deps.AuthController) }

To swap to a real rule engine, call openfeature.SetProvider(...) at startup with any OpenFeature-compatible provider . Application code stays unchanged.

See the Feature Flags API reference for the flag file format and the full FeatureFlagService API.

Accessing Configuration in Code

The config struct is available throughout your application via dependency injection:

// In a service type OrderService struct { repo interfaces.OrderRepository config *config.AppConfig } func NewOrderService(repo interfaces.OrderRepository, config *config.AppConfig) *OrderService { return &OrderService{repo: repo, config: config} } func (s *OrderService) GetAppURL() string { return s.config.App.URL }

Environment-Specific Configuration

A common pattern is to have a base config.yaml for development and override values in other environments:

Development — use config.yaml as-is with local defaults.

Staging — override with environment variables in your deployment:

GOFASTA_APP_ENV=staging GOFASTA_DATABASE_HOST=staging-db.internal GOFASTA_JWT_SECRET=staging-secret

Production — override all sensitive values:

GOFASTA_APP_ENV=production GOFASTA_APP_DEBUG=false GOFASTA_DATABASE_HOST=prod-db.internal GOFASTA_DATABASE_PASSWORD=prod-password GOFASTA_JWT_SECRET=prod-secret GOFASTA_REDIS_HOST=prod-redis.internal GOFASTA_MAIL_DRIVER=sendgrid GOFASTA_MAIL_SENDGRID_API_KEY=SG.prod-key

This approach keeps your config.yaml safe to commit to version control (it only contains development defaults) while production secrets are managed through environment variables or secret managers.

Next Steps

Last updated on