Files
pgsql-jellyfin/docs/FILE_BASED_CONFIG_SUMMARY.md
wjones 8f860a8ec3 Centralize build output and generate OS-specific startup.json
- 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
2026-02-26 14:21:26 -05:00

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):

  1. ./startup.json (current working directory)
  2. {AppDirectory}/startup.json
  3. {AppDirectory}/config/startup.json

🔧 Changes Made

New Files Created

  1. Jellyfin.Server/Resources/Configuration/startup.default.json - Default template
  2. startup.json.example - User-friendly example with documentation
  3. FILE_BASED_STARTUP_CONFIG.md - Comprehensive documentation

Code Changes

  1. Jellyfin.Server/Helpers/StartupHelpers.cs
    • Added LoadStartupConfiguration() method
    • Searches for startup.json in multiple locations
    • Integrates file-based config into path resolution
    • Priority: CLI > Env Var > Config File > Default

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.json readable 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

  1. FILE_BASED_STARTUP_CONFIG.md - Complete guide with examples
  2. startup.json.example - Template with examples and notes
  3. startup.default.json - Minimal template
  4. This summary - Quick reference

🚀 Getting Started

  1. Copy the example file:

    cp startup.json.example startup.json
    
  2. Edit with your paths:

    nano startup.json
    
  3. Place in one of these locations:

    • Next to jellyfin executable
    • In config subdirectory
    • In current working directory
  4. Start Jellyfin:

    jellyfin
    
  5. 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! 🚀