re-uploading work
This commit is contained in:
624
docs/configuration/configuration.md
Normal file
624
docs/configuration/configuration.md
Normal file
@@ -0,0 +1,624 @@
|
||||
# Configuration Guide
|
||||
|
||||
This guide explains how to configure the Attune automation platform using YAML configuration files.
|
||||
|
||||
## Overview
|
||||
|
||||
Attune uses a layered configuration system with YAML files as the primary configuration source. Configuration can be overridden using environment variables, making it flexible for different deployment scenarios.
|
||||
|
||||
## Configuration Loading Priority
|
||||
|
||||
Configuration is loaded in the following order (later sources override earlier ones):
|
||||
|
||||
1. **Base configuration file** (`config.yaml` or path from `ATTUNE_CONFIG` environment variable)
|
||||
2. **Environment-specific configuration** (e.g., `config.development.yaml`, `config.production.yaml`)
|
||||
3. **Environment variables** (prefix: `ATTUNE__`, separator: `__`)
|
||||
|
||||
This layered approach allows you to:
|
||||
- Keep common settings in `config.yaml`
|
||||
- Override settings per environment (dev, test, production)
|
||||
- Override sensitive values with environment variables (recommended for production)
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Copy the example configuration:**
|
||||
```bash
|
||||
cp config.example.yaml config.yaml
|
||||
```
|
||||
|
||||
2. **Edit the configuration:**
|
||||
```bash
|
||||
nano config.yaml
|
||||
```
|
||||
|
||||
3. **Set required values:**
|
||||
- Database URL
|
||||
- JWT secret key
|
||||
- Encryption key
|
||||
- CORS origins (if applicable)
|
||||
|
||||
4. **Run the application:**
|
||||
```bash
|
||||
cargo run --bin attune-api
|
||||
```
|
||||
|
||||
## Configuration File Structure
|
||||
|
||||
### Basic Example
|
||||
|
||||
```yaml
|
||||
service_name: attune
|
||||
environment: development
|
||||
|
||||
database:
|
||||
url: postgresql://postgres:postgres@localhost:5432/attune
|
||||
max_connections: 50
|
||||
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 8080
|
||||
cors_origins:
|
||||
- http://localhost:3000
|
||||
|
||||
security:
|
||||
jwt_secret: your-secret-key-here
|
||||
jwt_access_expiration: 3600
|
||||
|
||||
log:
|
||||
level: info
|
||||
format: json
|
||||
```
|
||||
|
||||
## Configuration Sections
|
||||
|
||||
### Service Metadata
|
||||
|
||||
```yaml
|
||||
service_name: attune # Service identifier
|
||||
environment: development # Environment: development, test, staging, production
|
||||
```
|
||||
|
||||
### Database Configuration
|
||||
|
||||
```yaml
|
||||
database:
|
||||
# PostgreSQL connection URL
|
||||
url: postgresql://username:password@host:port/database
|
||||
|
||||
# Connection pool settings
|
||||
max_connections: 50 # Maximum pool size
|
||||
min_connections: 5 # Minimum pool size
|
||||
connect_timeout: 30 # Connection timeout (seconds)
|
||||
idle_timeout: 600 # Idle connection timeout (seconds)
|
||||
|
||||
# Debugging
|
||||
log_statements: false # Log SQL statements (set true for debugging)
|
||||
```
|
||||
|
||||
**Environment variable override:**
|
||||
```bash
|
||||
export ATTUNE__DATABASE__URL=postgresql://user:pass@localhost/attune
|
||||
export ATTUNE__DATABASE__MAX_CONNECTIONS=100
|
||||
```
|
||||
|
||||
### Server Configuration
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: 0.0.0.0 # Bind address (0.0.0.0 for all interfaces)
|
||||
port: 8080 # HTTP port
|
||||
request_timeout: 30 # Request timeout (seconds)
|
||||
enable_cors: true # Enable CORS middleware
|
||||
|
||||
# Allowed CORS origins
|
||||
cors_origins:
|
||||
- http://localhost:3000
|
||||
- https://app.example.com
|
||||
|
||||
max_body_size: 10485760 # Max request body size (10MB in bytes)
|
||||
```
|
||||
|
||||
**Environment variable override:**
|
||||
```bash
|
||||
export ATTUNE__SERVER__PORT=3000
|
||||
export ATTUNE__SERVER__CORS_ORIGINS="https://app.com,https://www.app.com"
|
||||
```
|
||||
|
||||
### Security Configuration
|
||||
|
||||
```yaml
|
||||
security:
|
||||
# JWT secret for signing tokens (REQUIRED if enable_auth is true)
|
||||
# Generate with: openssl rand -base64 64
|
||||
jwt_secret: your-secret-key-here
|
||||
|
||||
# Token expiration times (seconds)
|
||||
jwt_access_expiration: 3600 # Access token: 1 hour
|
||||
jwt_refresh_expiration: 604800 # Refresh token: 7 days
|
||||
|
||||
# Encryption key for storing secrets (must be at least 32 characters)
|
||||
# Generate with: openssl rand -base64 32
|
||||
encryption_key: your-32-char-encryption-key-here
|
||||
|
||||
# Enable/disable authentication
|
||||
enable_auth: true
|
||||
```
|
||||
|
||||
**Environment variable override (recommended for production):**
|
||||
```bash
|
||||
export ATTUNE__SECURITY__JWT_SECRET=$(openssl rand -base64 64)
|
||||
export ATTUNE__SECURITY__ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||
```
|
||||
|
||||
### Logging Configuration
|
||||
|
||||
```yaml
|
||||
log:
|
||||
# Log level: trace, debug, info, warn, error
|
||||
level: info
|
||||
|
||||
# Log format: json (structured), pretty (human-readable)
|
||||
format: json
|
||||
|
||||
# Enable console output
|
||||
console: true
|
||||
|
||||
# Optional: write logs to file
|
||||
file: /var/log/attune/attune.log
|
||||
```
|
||||
|
||||
**Environment variable override:**
|
||||
```bash
|
||||
export ATTUNE__LOG__LEVEL=debug
|
||||
export ATTUNE__LOG__FORMAT=pretty
|
||||
```
|
||||
|
||||
### Redis Configuration (Optional)
|
||||
|
||||
```yaml
|
||||
redis:
|
||||
url: redis://localhost:6379
|
||||
pool_size: 10
|
||||
```
|
||||
|
||||
### Message Queue Configuration (Optional)
|
||||
|
||||
```yaml
|
||||
message_queue:
|
||||
url: amqp://guest:guest@localhost:5672/%2f
|
||||
exchange: attune
|
||||
enable_dlq: true # Enable dead letter queue
|
||||
message_ttl: 3600 # Message TTL (seconds)
|
||||
```
|
||||
|
||||
### Worker Configuration (Optional)
|
||||
|
||||
```yaml
|
||||
worker:
|
||||
name: attune-worker-1
|
||||
worker_type: local # local, remote, container
|
||||
max_concurrent_tasks: 10
|
||||
heartbeat_interval: 30 # seconds
|
||||
task_timeout: 300 # seconds
|
||||
```
|
||||
|
||||
## Environment-Specific Configuration
|
||||
|
||||
### Development Environment
|
||||
|
||||
Create `config.development.yaml`:
|
||||
|
||||
```yaml
|
||||
environment: development
|
||||
|
||||
database:
|
||||
url: postgresql://postgres:postgres@localhost:5432/attune
|
||||
log_statements: true
|
||||
|
||||
server:
|
||||
host: 127.0.0.1
|
||||
cors_origins:
|
||||
- http://localhost:3000
|
||||
- http://localhost:5173
|
||||
|
||||
log:
|
||||
level: debug
|
||||
format: pretty
|
||||
|
||||
security:
|
||||
jwt_secret: dev-secret-not-for-production
|
||||
jwt_access_expiration: 86400 # 24 hours for dev convenience
|
||||
```
|
||||
|
||||
### Production Environment
|
||||
|
||||
Create `config.production.yaml`:
|
||||
|
||||
```yaml
|
||||
environment: production
|
||||
|
||||
database:
|
||||
url: postgresql://attune_user:CHANGE_ME@db.example.com/attune
|
||||
max_connections: 100
|
||||
log_statements: false
|
||||
|
||||
server:
|
||||
cors_origins:
|
||||
- https://app.example.com
|
||||
- https://www.example.com
|
||||
|
||||
log:
|
||||
level: info
|
||||
format: json
|
||||
file: /var/log/attune/attune.log
|
||||
|
||||
security:
|
||||
# Override with environment variables!
|
||||
jwt_secret: CHANGE_ME_USE_ENV_VAR
|
||||
encryption_key: CHANGE_ME_USE_ENV_VAR
|
||||
```
|
||||
|
||||
**Important:** Always override sensitive values in production using environment variables:
|
||||
|
||||
```bash
|
||||
export ATTUNE__SECURITY__JWT_SECRET=$(openssl rand -base64 64)
|
||||
export ATTUNE__SECURITY__ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||
export ATTUNE__DATABASE__URL=postgresql://user:pass@db.example.com/attune
|
||||
```
|
||||
|
||||
### Test Environment
|
||||
|
||||
Create `config.test.yaml`:
|
||||
|
||||
```yaml
|
||||
environment: test
|
||||
|
||||
database:
|
||||
url: postgresql://postgres:postgres@localhost:5432/attune_test
|
||||
max_connections: 10
|
||||
|
||||
server:
|
||||
port: 0 # Random port for tests
|
||||
|
||||
log:
|
||||
level: warn
|
||||
format: pretty
|
||||
|
||||
security:
|
||||
jwt_secret: test-secret-not-secure
|
||||
jwt_access_expiration: 300 # 5 minutes
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
You can override any configuration value using environment variables with the `ATTUNE__` prefix and `__` separator for nested keys.
|
||||
|
||||
### Syntax
|
||||
|
||||
```
|
||||
ATTUNE__<section>__<key>=value
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# Database
|
||||
export ATTUNE__DATABASE__URL=postgresql://localhost/attune
|
||||
export ATTUNE__DATABASE__MAX_CONNECTIONS=100
|
||||
|
||||
# Server
|
||||
export ATTUNE__SERVER__PORT=8080
|
||||
export ATTUNE__SERVER__HOST=0.0.0.0
|
||||
|
||||
# Security
|
||||
export ATTUNE__SECURITY__JWT_SECRET=my-secret-key
|
||||
export ATTUNE__SECURITY__ENABLE_AUTH=true
|
||||
|
||||
# Logging
|
||||
export ATTUNE__LOG__LEVEL=debug
|
||||
export ATTUNE__LOG__FORMAT=pretty
|
||||
|
||||
# Arrays (comma-separated)
|
||||
export ATTUNE__SERVER__CORS_ORIGINS="https://app.com,https://www.app.com"
|
||||
```
|
||||
|
||||
### Boolean Values
|
||||
|
||||
Boolean values can be set using:
|
||||
- `true`, `1`, `yes`, `on` → true
|
||||
- `false`, `0`, `no`, `off` → false
|
||||
|
||||
```bash
|
||||
export ATTUNE__DATABASE__LOG_STATEMENTS=true
|
||||
export ATTUNE__SECURITY__ENABLE_AUTH=false
|
||||
```
|
||||
|
||||
## Custom Configuration File Path
|
||||
|
||||
By default, Attune looks for `config.yaml` in the current directory. You can specify a custom path:
|
||||
|
||||
```bash
|
||||
export ATTUNE_CONFIG=/path/to/custom-config.yaml
|
||||
cargo run --bin attune-api
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```bash
|
||||
ATTUNE_CONFIG=/etc/attune/config.yaml attune-api
|
||||
```
|
||||
|
||||
## Configuration Validation
|
||||
|
||||
The application validates configuration on startup and will fail with clear error messages if:
|
||||
|
||||
- Required fields are missing (e.g., JWT secret when auth is enabled)
|
||||
- Values are invalid (e.g., invalid log level)
|
||||
- Security requirements are not met (e.g., encryption key too short)
|
||||
|
||||
Example validation errors:
|
||||
|
||||
```
|
||||
Error: Configuration validation failed: JWT secret is required when authentication is enabled
|
||||
Error: Invalid log level: trace. Must be one of: ["trace", "debug", "info", "warn", "error"]
|
||||
Error: Encryption key must be at least 32 characters
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### 1. Never Commit Secrets
|
||||
|
||||
Add sensitive config files to `.gitignore`:
|
||||
|
||||
```gitignore
|
||||
config.yaml
|
||||
config.*.yaml
|
||||
!config.example.yaml
|
||||
!config.development.yaml
|
||||
!config.test.yaml
|
||||
```
|
||||
|
||||
### 2. Use Strong Secrets
|
||||
|
||||
Generate cryptographically secure secrets:
|
||||
|
||||
```bash
|
||||
# JWT secret (64 bytes, base64 encoded)
|
||||
openssl rand -base64 64
|
||||
|
||||
# Encryption key (32 bytes minimum, base64 encoded)
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
### 3. Environment Variables in Production
|
||||
|
||||
Always use environment variables for sensitive values in production:
|
||||
|
||||
```bash
|
||||
# In production deployment
|
||||
export ATTUNE__SECURITY__JWT_SECRET=$(openssl rand -base64 64)
|
||||
export ATTUNE__SECURITY__ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||
export ATTUNE__DATABASE__URL=postgresql://user:${DB_PASSWORD}@db.example.com/attune
|
||||
```
|
||||
|
||||
### 4. File Permissions
|
||||
|
||||
Restrict access to configuration files:
|
||||
|
||||
```bash
|
||||
chmod 600 config.yaml
|
||||
chown appuser:appuser config.yaml
|
||||
```
|
||||
|
||||
### 5. Separate Configs Per Environment
|
||||
|
||||
Use environment-specific files and never share production secrets with development:
|
||||
|
||||
```
|
||||
config.yaml # Base (committed)
|
||||
config.example.yaml # Example (committed)
|
||||
config.development.yaml # Development (committed, no real secrets)
|
||||
config.production.yaml # Production template (committed, placeholders only)
|
||||
config.yaml # Actual config (NOT committed, local overrides)
|
||||
```
|
||||
|
||||
## Docker/Container Deployments
|
||||
|
||||
### Option 1: Mount Configuration File
|
||||
|
||||
```bash
|
||||
docker run -v /path/to/config.yaml:/app/config.yaml attune-api
|
||||
```
|
||||
|
||||
### Option 2: Environment Variables (Recommended)
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
-e ATTUNE__DATABASE__URL=postgresql://db/attune \
|
||||
-e ATTUNE__SECURITY__JWT_SECRET=$(cat /run/secrets/jwt_secret) \
|
||||
-e ATTUNE__SERVER__PORT=8080 \
|
||||
attune-api
|
||||
```
|
||||
|
||||
### Docker Compose Example
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
api:
|
||||
image: attune-api
|
||||
environment:
|
||||
ATTUNE__DATABASE__URL: postgresql://postgres:postgres@db:5432/attune
|
||||
ATTUNE__SERVER__PORT: 8080
|
||||
ATTUNE__LOG__LEVEL: info
|
||||
secrets:
|
||||
- jwt_secret
|
||||
- encryption_key
|
||||
command: sh -c "
|
||||
export ATTUNE__SECURITY__JWT_SECRET=$$(cat /run/secrets/jwt_secret) &&
|
||||
export ATTUNE__SECURITY__ENCRYPTION_KEY=$$(cat /run/secrets/encryption_key) &&
|
||||
attune-api
|
||||
"
|
||||
|
||||
secrets:
|
||||
jwt_secret:
|
||||
file: ./secrets/jwt_secret.txt
|
||||
encryption_key:
|
||||
file: ./secrets/encryption_key.txt
|
||||
```
|
||||
|
||||
## Kubernetes Deployments
|
||||
|
||||
### ConfigMap for Base Configuration
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: attune-config
|
||||
data:
|
||||
config.yaml: |
|
||||
service_name: attune
|
||||
environment: production
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 8080
|
||||
log:
|
||||
level: info
|
||||
format: json
|
||||
```
|
||||
|
||||
### Secrets for Sensitive Values
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: attune-secrets
|
||||
type: Opaque
|
||||
stringData:
|
||||
jwt-secret: "your-base64-jwt-secret"
|
||||
encryption-key: "your-base64-encryption-key"
|
||||
database-url: "postgresql://user:pass@db/attune"
|
||||
```
|
||||
|
||||
### Deployment
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: attune-api
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: api
|
||||
image: attune-api:latest
|
||||
env:
|
||||
- name: ATTUNE__SECURITY__JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: attune-secrets
|
||||
key: jwt-secret
|
||||
- name: ATTUNE__SECURITY__ENCRYPTION_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: attune-secrets
|
||||
key: encryption-key
|
||||
- name: ATTUNE__DATABASE__URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: attune-secrets
|
||||
key: database-url
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config.yaml
|
||||
subPath: config.yaml
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: attune-config
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Configuration Not Loading
|
||||
|
||||
1. **Check file exists:**
|
||||
```bash
|
||||
ls -la config.yaml
|
||||
```
|
||||
|
||||
2. **Check YAML syntax:**
|
||||
```bash
|
||||
# Install yq if needed: brew install yq
|
||||
yq eval config.yaml
|
||||
```
|
||||
|
||||
3. **Check environment variable:**
|
||||
```bash
|
||||
echo $ATTUNE_CONFIG
|
||||
```
|
||||
|
||||
### Environment Variables Not Working
|
||||
|
||||
1. **Check variable name format:**
|
||||
- Must start with `ATTUNE__`
|
||||
- Use double underscores for nesting
|
||||
- Case-sensitive
|
||||
|
||||
2. **Verify variable is set:**
|
||||
```bash
|
||||
env | grep ATTUNE
|
||||
```
|
||||
|
||||
3. **Check for typos:**
|
||||
```bash
|
||||
export ATTUNE__DATABASE__URL=... # Correct
|
||||
export ATTUNE_DATABASE_URL=... # Wrong! (single underscore)
|
||||
```
|
||||
|
||||
### Validation Errors
|
||||
|
||||
Enable debug logging to see detailed configuration:
|
||||
|
||||
```bash
|
||||
ATTUNE__LOG__LEVEL=debug cargo run --bin attune-api
|
||||
```
|
||||
|
||||
## Migration from .env Files
|
||||
|
||||
If you're migrating from `.env` files, here's a conversion guide:
|
||||
|
||||
### Before (.env):
|
||||
```bash
|
||||
ATTUNE__DATABASE__URL=postgresql://localhost/attune
|
||||
ATTUNE__SERVER__PORT=8080
|
||||
ATTUNE__LOG__LEVEL=info
|
||||
ATTUNE__SECURITY__JWT_SECRET=my-secret
|
||||
```
|
||||
|
||||
### After (config.yaml):
|
||||
```yaml
|
||||
database:
|
||||
url: postgresql://localhost/attune
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
log:
|
||||
level: info
|
||||
|
||||
security:
|
||||
jwt_secret: my-secret
|
||||
```
|
||||
|
||||
**Note:** You can still use environment variables for overrides, but the base configuration is now in YAML.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Quick Start Guide](quick-start.md)
|
||||
- [Authentication Documentation](authentication.md)
|
||||
- [API Reference](api-reference.md)
|
||||
- [Deployment Guide](deployment.md)
|
||||
Reference in New Issue
Block a user