Skip to content

Config Manager

The Config Manager provides a unified configuration system that loads settings from multiple sources with intelligent merging and priority handling.

Settings are loaded in the following order (highest to lowest priority):

  1. Command line arguments (--host, --port)
  2. Environment variables (SIDESEAT_HOST, SIDESEAT_PORT)
  3. Workdir config (./sideseat.json)
  4. User config (~/.sideseat/config.json)
  5. Default values

Higher priority sources override lower priority sources. Objects are deep-merged, allowing partial overrides.

Located in the user config directory. This file is optional and provides user-level defaults.

{
"server": {
"host": "127.0.0.1",
"port": 5001
},
"logging": {
"level": "info",
"format": "compact"
}
}

Located in the current working directory. Project-specific settings that override user config.

{
"server": {
"port": 3000
},
"logging": {
"level": "debug"
}
}
VariableDescriptionDefault
SIDESEAT_HOSTServer host address127.0.0.1
SIDESEAT_PORTServer port5001
SIDESEAT_LOGLog level/filterinfo
SIDESEAT_AUTH_ENABLEDEnable/disable authenticationtrue
SIDESEAT_CONFIG_DIROverride config directoryPlatform default
SIDESEAT_DATA_DIROverride data directoryPlatform default
SIDESEAT_CACHE_DIROverride cache directoryPlatform default
Terminal window
# Example: Run on a different port
export SIDESEAT_PORT=8080
sideseat start
# Or pass directly
SIDESEAT_PORT=8080 sideseat start
Terminal window
sideseat start --host 0.0.0.0 --port 3000
sideseat start -H 0.0.0.0 -p 3000 # Short form
sideseat start --no-auth # Disable authentication

CLI arguments have the highest priority and always override other sources.

{
"server": {
"host": "127.0.0.1",
"port": 5001
},
"logging": {
"level": "info",
"format": "compact"
},
"storage": {
"config_dir": "/custom/config/path",
"data_dir": "/custom/data/path",
"cache_dir": "/custom/cache/path"
},
"auth": {
"enabled": true
}
}
FieldTypeDefaultDescription
hoststring"127.0.0.1"Server bind address
portnumber5001Server port
FieldTypeDefaultDescription
levelstring"info"Log level (trace, debug, info, warn, error)
formatstring"compact"Log output format
FieldTypeDefaultDescription
config_dirstringnullOverride config directory path
data_dirstringnullOverride data directory path
cache_dirstringnullOverride cache directory path
FieldTypeDefaultDescription
enabledbooleantrueEnable/disable authentication

Authentication can be disabled via:

  • Config file: "auth": { "enabled": false }
  • Environment variable: SIDESEAT_AUTH_ENABLED=false
  • CLI flag: --no-auth

Configuration objects are deep-merged, not replaced. This allows partial overrides:

// User config (~/.sideseat/config.json)
{
"server": {
"host": "127.0.0.1",
"port": 5001
},
"logging": {
"level": "info",
"format": "compact"
}
}
// Workdir config (./sideseat.json)
{
"server": {
"port": 3000
},
"logging": {
"level": "debug"
}
}
// Resulting merged config:
{
"server": {
"host": "127.0.0.1", // From user config
"port": 3000 // From workdir config (higher priority)
},
"logging": {
"level": "debug", // From workdir config
"format": "compact" // From user config
}
}
pub struct CliConfig {
pub host: Option<String>,
pub port: Option<u16>,
pub no_auth: bool,
}
pub struct Config {
pub server: ServerConfig,
pub logging: LoggingConfig,
pub storage: StorageConfig,
pub auth: AuthConfig,
}
pub struct ServerConfig {
pub host: String,
pub port: u16,
}
pub struct LoggingConfig {
pub level: String,
pub format: String,
}
pub struct StorageConfig {
pub config_dir: Option<String>,
pub data_dir: Option<String>,
pub cache_dir: Option<String>,
}
pub struct AuthConfig {
pub enabled: bool,
}
MethodDescription
init(storage, cli_args)Initialize config from all sources
config()Get reference to merged configuration
sources()Get all configuration sources
loaded_sources()Get only successfully loaded sources
use sideseat::core::{ConfigManager, CliConfig, StorageManager};
// Initialize storage first
let storage = StorageManager::init().await?;
// Create CLI config from parsed arguments
let cli_config = CliConfig {
host: Some("0.0.0.0".to_string()),
port: None,
};
// Initialize config manager
let config_manager = ConfigManager::init(&storage, &cli_config)?;
let config = config_manager.config();
println!("Server: {}:{}", config.server.host, config.server.port);
println!("Log level: {}", config.logging.level);
// List loaded configuration sources
for source in config_manager.loaded_sources() {
if let Some(ref path) = source.path {
println!("Loaded from: {}", path.display());
}
}

The Config Manager returns detailed errors for invalid configuration files:

Invalid JSON in '/home/user/.sideseat/config.json' at line 5, column 12: expected `,` or `}`

Common error scenarios:

  • Invalid JSON syntax (returns error with line/column)
  • File read permission denied
  • Invalid port number in environment variable (warning logged, value ignored)

Missing configuration files are silently skipped and do not cause errors.

SideSeat loads environment variables from a .env file in the current directory using dotenvy. This is processed before configuration initialization.

.env
SIDESEAT_HOST=0.0.0.0
SIDESEAT_PORT=8080
SIDESEAT_LOG=debug
  1. Use workdir config for project settings - Keep project-specific settings in sideseat.json
  2. Use user config for personal defaults - Store your preferred defaults in ~/.sideseat/config.json
  3. Use environment variables for deployment - Override settings without modifying files
  4. Use CLI arguments for one-off changes - Quick overrides without changing any files
  5. Partial configs are fine - Only specify the settings you want to override
  6. Don’t store secrets in config files - Use the Secret Manager for credentials