Configuration
Learn how to configure your Strav application for different environments and customize its behavior.
Configuration Files
Strav uses a centralized configuration system. All configuration files are stored in the config/ directory:
config/
├── app.ts # Application settings
├── database.ts # Database connections
├── cache.ts # Cache stores
├── mail.ts # Mail drivers
├── queue.ts # Queue connections
├── storage.ts # File storage
├── session.ts # Session configuration
├── auth.ts # Authentication settings
└── services.ts # Third-party services
Environment Variables
Strav uses environment variables for sensitive data and environment-specific settings. The .env file in your project root contains these variables.
Loading Environment Variables
Environment variables are loaded automatically when the application starts. Use the env() helper in config files:
import { env } from '@strav/kernel'
export default {
name: env('APP_NAME', 'My App'), // With default value
debug: env.bool('APP_DEBUG', false), // Boolean casting
port: env.int('APP_PORT', 3000), // Integer casting
rate: env.float('RATE_LIMIT', 0.5), // Float casting
// For arrays, use config helpers or parse manually:
features: env('FEATURES', '').split(',').filter(Boolean),
// For required values, throw manually if needed:
apiKey: env('API_KEY') || (() => { throw new Error('API_KEY required') })()
}
Environment File Priority
Strav loads environment files in this order (later files override earlier ones):
.env- Default values.env.local- Local overrides (gitignored).env.[environment]- Environment-specific (e.g.,.env.production).env.[environment].local- Local environment overrides (gitignored)
Application Configuration
config/app.ts
import { env } from '@strav/kernel'
export default {
// Application name
name: env('APP_NAME', 'Strav Application'),
// Environment (local, development, staging, production)
env: env('APP_ENV', 'production'),
// Debug mode
debug: env.bool('APP_DEBUG', false),
// Application URL
url: env('APP_URL', 'http://localhost:3000'),
// Server port
port: env.int('APP_PORT', 3000),
// Encryption key for cookies and sessions
key: env('APP_KEY'),
// Timezone
timezone: 'UTC',
// Locale
locale: 'en',
// Available locales
locales: ['en', 'es', 'fr', 'de'],
// Logging
log: {
level: env('LOG_LEVEL', 'info'),
channels: ['file', 'console'],
},
}
Database Configuration
config/database.ts
import { env } from '@strav/kernel'
export default {
// Default connection
default: env('DB_CONNECTION', 'postgres'),
// Connection configurations
connections: {
postgres: {
driver: 'postgres',
host: env('DB_HOST', '127.0.0.1'),
port: env.int('DB_PORT', 5432),
database: env('DB_DATABASE', 'strav'),
username: env('DB_USER', 'postgres'),
password: env('DB_PASSWORD', ''),
// Connection pool settings
pool: {
min: env.int('DB_POOL_MIN', 2),
max: env.int('DB_POOL_MAX', 10),
},
// SSL configuration
ssl: env.bool('DB_SSL', false) ? {
rejectUnauthorized: false,
ca: env('DB_SSL_CA'),
} : false,
},
// Read replica configuration
read: {
driver: 'postgres',
host: env('DB_READ_HOST', '127.0.0.1'),
port: env.int('DB_READ_PORT', 5432),
database: env('DB_DATABASE', 'strav'),
username: env('DB_READ_USER', 'postgres'),
password: env('DB_READ_PASSWORD', ''),
},
},
// Migration settings
migrations: {
table: '_strav_migrations',
directory: './database/migrations',
},
}
Cache Configuration
config/cache.ts
import { env } from '@strav/kernel'
export default {
// Default cache store
default: env('CACHE_DRIVER', 'memory'),
// Cache stores
stores: {
memory: {
driver: 'memory',
max: 100, // Maximum items
ttl: 3600, // Default TTL in seconds
},
redis: {
driver: 'redis',
connection: 'cache',
},
database: {
driver: 'database',
table: 'cache',
connection: 'postgres',
},
file: {
driver: 'file',
path: './storage/cache',
},
},
// Cache key prefix
prefix: env('CACHE_PREFIX', 'strav_cache_'),
}
Session Configuration
config/session.ts
import { env } from '@strav/kernel'
export default {
// Session driver (cookie, database, redis, memory)
driver: env('SESSION_DRIVER', 'cookie'),
// Session cookie name
name: 'strav_session',
// Session lifetime in seconds
lifetime: env.int('SESSION_LIFETIME', 7200), // 2 hours
// Expire on browser close
expire_on_close: false,
// Encrypt session data
encrypt: true,
// Session cookie path
path: '/',
// Session cookie domain
domain: env('SESSION_DOMAIN'),
// HTTPS only cookies
secure: env('APP_ENV') === 'production',
// HTTP only (no JavaScript access)
httpOnly: true,
// Same-site cookie attribute
sameSite: 'lax',
// Database table (when using database driver)
table: 'sessions',
// Redis connection (when using redis driver)
connection: 'session',
}
Mail Configuration
config/mail.ts
import { env } from '@strav/kernel'
export default {
// Default mailer
default: env('MAIL_DRIVER', 'smtp'),
// Mailer configurations
mailers: {
smtp: {
transport: 'smtp',
host: env('MAIL_HOST', 'smtp.mailgun.org'),
port: env.int('MAIL_PORT', 587),
encryption: env('MAIL_ENCRYPTION', 'tls'),
username: env('MAIL_USERNAME'),
password: env('MAIL_PASSWORD'),
},
sendmail: {
transport: 'sendmail',
path: '/usr/sbin/sendmail -bs',
},
log: {
transport: 'log',
channel: 'mail',
},
array: {
transport: 'array',
},
},
// Global "from" address
from: {
address: env('MAIL_FROM_ADDRESS', 'hello@example.com'),
name: env('MAIL_FROM_NAME', 'Example'),
},
// Markdown mail settings
markdown: {
theme: 'default',
paths: ['./resources/views/emails'],
},
}
Storage Configuration
config/storage.ts
import { env } from '@strav/kernel'
export default {
// Default disk
default: env('STORAGE_DISK', 'local'),
// Storage disks
disks: {
local: {
driver: 'local',
root: './storage/app',
url: '/storage',
visibility: 'private',
},
public: {
driver: 'local',
root: './storage/app/public',
url: '/storage',
visibility: 'public',
},
s3: {
driver: 's3',
key: env('AWS_ACCESS_KEY_ID'),
secret: env('AWS_SECRET_ACCESS_KEY'),
region: env('AWS_DEFAULT_REGION', 'us-east-1'),
bucket: env('AWS_BUCKET'),
url: env('AWS_URL'),
endpoint: env('AWS_ENDPOINT'),
},
temp: {
driver: 'local',
root: './storage/temp',
visibility: 'private',
// Auto-delete files older than 24 hours
cleanup: true,
cleanupAge: 86400,
},
},
// File upload settings
uploads: {
maxSize: '10MB',
allowedTypes: ['image/jpeg', 'image/png', 'application/pdf'],
directory: 'uploads',
},
}
Custom Configuration Files
You can create custom configuration files for your application:
config/payment.ts
import { env } from '@strav/kernel'
export default {
stripe: {
key: env('STRIPE_KEY'),
secret: env('STRIPE_SECRET'),
webhook: env('STRIPE_WEBHOOK_SECRET'),
currency: 'usd',
},
paypal: {
client: env('PAYPAL_CLIENT_ID'),
secret: env('PAYPAL_SECRET'),
mode: env('PAYPAL_MODE', 'sandbox'),
},
}
Accessing Configuration
Use the Configuration service to access config values:
import { config } from '@strav/kernel'
// Get a config value
const appName = config.get('app.name')
const dbHost = config.get('database.connections.postgres.host')
// Get with default value
const timeout = config.get('app.timeout', 30)
// Get entire config file
const mailConfig = config.get('mail')
// Check if config exists
if (config.has('services.stripe')) {
// Stripe is configured
}
// Set config at runtime (not persisted)
config.set('app.maintenance', true)
Environment-Specific Configuration
Load different configurations based on environment:
import { env } from '@strav/kernel'
const environment = env('APP_ENV', 'production')
export default {
features: {
registration: environment !== 'production',
api: ['production', 'staging'].includes(environment),
debug_toolbar: environment === 'local',
},
services: environment === 'production' ? {
cdn: 'https://cdn.example.com',
analytics: true,
} : {
cdn: '',
analytics: false,
},
}
Security Best Practices
- Never commit
.envfiles with sensitive data to version control - Use
.env.exampleas a template with dummy values - Rotate
APP_KEYperiodically - Use different database credentials for different environments
- Enable SSL/TLS for production databases
- Use secrets management services in production (AWS Secrets Manager, HashiCorp Vault)
Configuration Validation
Validate your configuration at startup:
// app/providers/config_validator.ts
import { ServiceProvider, ConfigurationException } from '@strav/kernel'
export class ConfigValidatorProvider extends ServiceProvider {
name = 'config-validator'
boot(app) {
const config = app.resolve(Configuration)
// Validate required configurations
const required = [
'app.key',
'database.connections.postgres.host',
'mail.from.address',
]
for (const key of required) {
if (!config.has(key) || !config.get(key)) {
throw new ConfigurationException(`Missing required config: ${key}`)
}
}
// Validate config values
const port = config.get('app.port')
if (port < 1 || port > 65535) {
throw new ConfigurationException('Invalid port number')
}
}
}