Files
pgsql-jellyfin/FILE_BASED_CONFIG_SUMMARY.md
T
wjones c38adfc0f7 Add file-based startup config & temp dir option
Added support for configuring all major Jellyfin paths (data, config, cache, log, temp, web) via a `startup.json` file, with priority after CLI and environment variables. Introduced a new `TempDir` option, configurable through CLI, env var, or config file, with backward-compatible defaults. Refactored path resolution logic to integrate file-based config and ensure directory creation. Updated constructors and CLI options to support temp directory. Improved EF Core migration error handling and logging. Added comprehensive documentation and example config files. All changes are backward compatible.
2026-02-25 15:18:23 -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! 🚀