- All DLLs now output to lib\[Configuration]\[TargetFramework]\ at repo root (see Directory.Build.props) - .gitignore updated to exclude /lib/ - On first run, startup.json is auto-generated with OS-appropriate default paths (Windows, Linux, macOS, or portable) - Removes null/example config; generated config is immediately usable and clearly documented - Extensive new documentation: build output, startup.json logic, visual guides, and code proofs - Publish profile now deletes existing files for clean deploys - No breaking changes: existing startup.json files are preserved - Improves first-run UX, deployment, and cross-platform consistency
8.3 KiB
Summary: File-Based Startup Configuration
✅ Implementation Complete!
Yes, startup options can now be configured via file in addition to command-line arguments and environment variables!
🎯 Configuration Methods
Jellyfin now supports three ways to configure startup paths:
1. 📄 Configuration File (NEW!)
- File:
startup.json - Format: JSON
- Location: Current directory, app directory, or config subdirectory
- Best for: Production servers, containers, persistent configurations
2. 🔧 Command-Line Arguments
- Example:
--datadir /var/lib/jellyfin - Best for: Testing, one-time overrides, debugging
3. 🌍 Environment Variables
- Example:
JELLYFIN_DATA_DIR=/var/lib/jellyfin - Best for: System-wide settings, CI/CD, user-specific overrides
📊 Priority Order
When a path is configured in multiple places, Jellyfin uses this priority (highest to lowest):
1. Command-line options (--datadir, etc.)
↓
2. Environment variables (JELLYFIN_DATA_DIR, etc.)
↓
3. Configuration file (startup.json)
↓
4. Default values
📁 Configuration File Format
Create a file named startup.json:
{
"Paths": {
"DataDir": "/var/lib/jellyfin",
"ConfigDir": "/etc/jellyfin",
"CacheDir": "/var/cache/jellyfin",
"LogDir": "/var/log/jellyfin",
"TempDir": "/var/tmp/jellyfin",
"WebDir": "/usr/share/jellyfin/web"
}
}
All Properties are Optional!
You can omit any property or set it to null, and Jellyfin will fall back to environment variables or defaults:
{
"Paths": {
"DataDir": "/custom/data"
}
}
📍 File Locations
The startup.json file is searched in these locations (first found is used):
./startup.json(current working directory){AppDirectory}/startup.json{AppDirectory}/config/startup.json
🔧 Changes Made
New Files Created
- Jellyfin.Server/Resources/Configuration/startup.default.json - Default template
- startup.json.example - User-friendly example with documentation
- FILE_BASED_STARTUP_CONFIG.md - Comprehensive documentation
Code Changes
- Jellyfin.Server/Helpers/StartupHelpers.cs
- Added
LoadStartupConfiguration()method - Searches for
startup.jsonin multiple locations - Integrates file-based config into path resolution
- Priority: CLI > Env Var > Config File > Default
- Added
Modified Path Resolution
All six paths now support configuration file:
- DataDir
- ConfigDir
- CacheDir
- LogDir
- TempDir
- WebDir
💡 Use Cases
1. Production Server
{
"Paths": {
"DataDir": "/var/lib/jellyfin",
"ConfigDir": "/etc/jellyfin",
"CacheDir": "/var/cache/jellyfin",
"LogDir": "/var/log/jellyfin",
"TempDir": "/var/tmp/jellyfin"
}
}
2. Docker Container
{
"Paths": {
"DataDir": "/data",
"ConfigDir": "/config",
"CacheDir": "/cache",
"TempDir": "/temp"
}
}
3. Portable Installation
{
"Paths": {
"DataDir": "./data",
"ConfigDir": "./config",
"CacheDir": "./cache",
"LogDir": "./logs",
"TempDir": "./temp"
}
}
4. Performance Optimization
{
"Paths": {
"DataDir": "/mnt/hdd/jellyfin/data",
"CacheDir": "/mnt/ssd/jellyfin/cache",
"TempDir": "/mnt/nvme/jellyfin/temp"
}
}
✅ Validation
When Jellyfin starts, it logs the configuration file being used:
Loaded startup configuration from: /path/to/startup.json
If the file has errors:
Warning: Failed to load startup configuration from /path/to/startup.json: [error]
All resolved paths are logged:
[INF] Program data path: /var/lib/jellyfin
[INF] Config directory path: /etc/jellyfin
[INF] Cache path: /var/cache/jellyfin
[INF] Log directory path: /var/log/jellyfin
[INF] Temp directory path: /var/tmp/jellyfin
[INF] Web resources path: /usr/share/jellyfin/web
🎨 Example Scenarios
Scenario 1: Basic File Configuration
startup.json:
{
"Paths": {
"DataDir": "/var/lib/jellyfin"
}
}
Result: DataDir from file, all others use defaults
Scenario 2: Mixed Configuration
startup.json:
{
"Paths": {
"DataDir": "/var/lib/jellyfin",
"ConfigDir": "/etc/jellyfin"
}
}
Environment:
export JELLYFIN_TEMP_DIR=/fast-storage/temp
Result:
- DataDir & ConfigDir from file
- TempDir from environment variable
- Others use defaults
Scenario 3: Override Everything
startup.json:
{
"Paths": {
"DataDir": "/var/lib/jellyfin"
}
}
Command line:
jellyfin --datadir /tmp/testing
Result: DataDir from command line (highest priority)
📦 Migration Guide
From Environment Variables
Before:
export JELLYFIN_DATA_DIR=/var/lib/jellyfin
export JELLYFIN_CONFIG_DIR=/etc/jellyfin
export JELLYFIN_CACHE_DIR=/var/cache/jellyfin
After:
Create startup.json:
{
"Paths": {
"DataDir": "/var/lib/jellyfin",
"ConfigDir": "/etc/jellyfin",
"CacheDir": "/var/cache/jellyfin"
}
}
Then remove environment variables.
From Command-Line Arguments
Before:
jellyfin --datadir /var/lib/jellyfin --configdir /etc/jellyfin --cachedir /var/cache/jellyfin
After:
Create startup.json and run:
jellyfin
🐳 Docker Integration
docker-compose.yml:
version: '3.8'
services:
jellyfin:
image: jellyfin/jellyfin
volumes:
- ./startup.json:/app/startup.json
- jellyfin_data:/data
- jellyfin_config:/config
- jellyfin_cache:/cache
startup.json:
{
"Paths": {
"DataDir": "/data",
"ConfigDir": "/config",
"CacheDir": "/cache"
}
}
🔒 Security
- Keep
startup.jsonreadable only by Jellyfin user - Don't commit sensitive paths to public repositories
- Use file permissions:
chmod 600 startup.json - Consider separate files per environment
📚 Benefits
Advantages Over Environment Variables
✅ Portable - Easy to copy between systems
✅ Version Control - Track changes in Git
✅ Self-Documenting - Clear structure
✅ Persistent - Survives reboots
✅ No Shell Escaping - No quoting issues
✅ Easy Editing - Simple text file
Advantages Over Command-Line
✅ Permanent - No need to repeat options
✅ Complex Configurations - Handle many options easily
✅ Documentation - Can include comments
✅ Consistency - Same config every time
🏗️ Build Status
✅ Build Successful
✅ All tests passing
✅ Backward compatible - existing configurations continue to work
✅ No breaking changes
📖 Documentation Created
- FILE_BASED_STARTUP_CONFIG.md - Complete guide with examples
- startup.json.example - Template with examples and notes
- startup.default.json - Minimal template
- This summary - Quick reference
🚀 Getting Started
-
Copy the example file:
cp startup.json.example startup.json -
Edit with your paths:
nano startup.json -
Place in one of these locations:
- Next to jellyfin executable
- In config subdirectory
- In current working directory
-
Start Jellyfin:
jellyfin -
Verify it's loaded: Check logs for "Loaded startup configuration from:"
📊 Complete Feature Matrix
| Path | CLI Option | Env Variable | Config File | Default |
|---|---|---|---|---|
| Data | ✅ --datadir |
✅ JELLYFIN_DATA_DIR |
✅ Paths:DataDir |
✅ OS-specific |
| Config | ✅ --configdir |
✅ JELLYFIN_CONFIG_DIR |
✅ Paths:ConfigDir |
✅ OS-specific |
| Cache | ✅ --cachedir |
✅ JELLYFIN_CACHE_DIR |
✅ Paths:CacheDir |
✅ OS-specific |
| Logs | ✅ --logdir |
✅ JELLYFIN_LOG_DIR |
✅ Paths:LogDir |
✅ {data}/log |
| Temp | ✅ --tempdir |
✅ JELLYFIN_TEMP_DIR |
✅ Paths:TempDir |
✅ {system_temp}/jellyfin |
| Web | ✅ --webdir |
✅ JELLYFIN_WEB_DIR |
✅ Paths:WebDir |
✅ wwwroot or jellyfin-web |
🎉 Result
All startup options are now configurable via file, in addition to command-line and environment variables!
This provides maximum flexibility for all deployment scenarios:
- Development
- Testing
- Staging
- Production
- Containers
- Portable installations
- Multiple instances
Choose the configuration method that works best for your use case! 🚀