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
This commit is contained in:
@@ -0,0 +1,372 @@
|
||||
# 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`:
|
||||
|
||||
```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:
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "/var/lib/jellyfin",
|
||||
"ConfigDir": "/etc/jellyfin",
|
||||
"CacheDir": "/var/cache/jellyfin",
|
||||
"LogDir": "/var/log/jellyfin",
|
||||
"TempDir": "/var/tmp/jellyfin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Docker Container
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "/data",
|
||||
"ConfigDir": "/config",
|
||||
"CacheDir": "/cache",
|
||||
"TempDir": "/temp"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Portable Installation
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "./data",
|
||||
"ConfigDir": "./config",
|
||||
"CacheDir": "./cache",
|
||||
"LogDir": "./logs",
|
||||
"TempDir": "./temp"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Performance Optimization
|
||||
```json
|
||||
{
|
||||
"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:**
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "/var/lib/jellyfin"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Result:** DataDir from file, all others use defaults
|
||||
|
||||
### Scenario 2: Mixed Configuration
|
||||
**startup.json:**
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "/var/lib/jellyfin",
|
||||
"ConfigDir": "/etc/jellyfin"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Environment:**
|
||||
```bash
|
||||
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:**
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "/var/lib/jellyfin"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Command line:**
|
||||
```bash
|
||||
jellyfin --datadir /tmp/testing
|
||||
```
|
||||
**Result:** DataDir from command line (highest priority)
|
||||
|
||||
## 📦 Migration Guide
|
||||
|
||||
### From Environment Variables
|
||||
|
||||
**Before:**
|
||||
```bash
|
||||
export JELLYFIN_DATA_DIR=/var/lib/jellyfin
|
||||
export JELLYFIN_CONFIG_DIR=/etc/jellyfin
|
||||
export JELLYFIN_CACHE_DIR=/var/cache/jellyfin
|
||||
```
|
||||
|
||||
**After:**
|
||||
Create `startup.json`:
|
||||
```json
|
||||
{
|
||||
"Paths": {
|
||||
"DataDir": "/var/lib/jellyfin",
|
||||
"ConfigDir": "/etc/jellyfin",
|
||||
"CacheDir": "/var/cache/jellyfin"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then remove environment variables.
|
||||
|
||||
### From Command-Line Arguments
|
||||
|
||||
**Before:**
|
||||
```bash
|
||||
jellyfin --datadir /var/lib/jellyfin --configdir /etc/jellyfin --cachedir /var/cache/jellyfin
|
||||
```
|
||||
|
||||
**After:**
|
||||
Create `startup.json` and run:
|
||||
```bash
|
||||
jellyfin
|
||||
```
|
||||
|
||||
## 🐳 Docker Integration
|
||||
|
||||
**docker-compose.yml:**
|
||||
```yaml
|
||||
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:**
|
||||
```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:**
|
||||
```bash
|
||||
cp startup.json.example startup.json
|
||||
```
|
||||
|
||||
2. **Edit with your paths:**
|
||||
```bash
|
||||
nano startup.json
|
||||
```
|
||||
|
||||
3. **Place in one of these locations:**
|
||||
- Next to jellyfin executable
|
||||
- In config subdirectory
|
||||
- In current working directory
|
||||
|
||||
4. **Start Jellyfin:**
|
||||
```bash
|
||||
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! 🚀
|
||||
Reference in New Issue
Block a user