8f860a8ec3
- 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
407 lines
10 KiB
Markdown
407 lines
10 KiB
Markdown
# File-Based Startup Configuration
|
|
|
|
## Overview
|
|
Jellyfin now supports file-based configuration for all startup paths in addition to command-line options and environment variables. This provides a persistent, portable way to configure your Jellyfin installation.
|
|
|
|
**New in this version:** The `startup.json` file is **automatically created** on first startup if it doesn't exist, with example configurations for Linux, Windows, and portable installations. See [AUTO_GENERATED_STARTUP_CONFIG.md](AUTO_GENERATED_STARTUP_CONFIG.md) for details.
|
|
|
|
## Configuration Priority
|
|
|
|
When determining which path to use, Jellyfin follows this priority (highest to lowest):
|
|
|
|
1. **Command-line options** (e.g., `--datadir`)
|
|
2. **Environment variables** (e.g., `JELLYFIN_DATA_DIR`)
|
|
3. **Configuration file** (`startup.json`)
|
|
4. **Default values**
|
|
|
|
This allows you to set defaults in a file, override them with environment variables for different environments, and temporarily override with command-line options for testing.
|
|
|
|
## Automatic File Creation ⭐ NEW
|
|
|
|
On first startup, if no `startup.json` file is found, Jellyfin will automatically create one with:
|
|
- All path properties set to `null` (uses defaults)
|
|
- Example configurations for Linux, Windows, and portable setups
|
|
- Inline documentation and comments
|
|
|
|
**You'll see:**
|
|
```
|
|
Created default startup configuration at: /path/to/startup.json
|
|
You can customize this file to set default paths for Jellyfin.
|
|
```
|
|
|
|
Simply edit the file and restart Jellyfin to apply your custom paths. See [AUTO_GENERATED_STARTUP_CONFIG.md](AUTO_GENERATED_STARTUP_CONFIG.md) for complete details on the auto-generation feature.
|
|
|
|
## Configuration File Location
|
|
|
|
The `startup.json` file is searched in the following locations (in order):
|
|
|
|
1. **Current working directory**: `./startup.json`
|
|
2. **Application directory**: `{AppDir}/startup.json`
|
|
3. **Config subdirectory**: `{AppDir}/config/startup.json`
|
|
|
|
The first file found will be used.
|
|
|
|
## File Format
|
|
|
|
Create a file named `startup.json` with the following structure (or let it be auto-generated):
|
|
|
|
```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"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Supported Properties
|
|
|
|
All path properties are **optional**. Any property can be set to `null` or omitted entirely, and the system will fall back to environment variables or defaults.
|
|
|
|
| Property | Description | Equivalent CLI | Equivalent Env Var |
|
|
|----------|-------------|----------------|-------------------|
|
|
| `DataDir` | Database and data files | `--datadir` | `JELLYFIN_DATA_DIR` |
|
|
| `ConfigDir` | Configuration files | `--configdir` | `JELLYFIN_CONFIG_DIR` |
|
|
| `CacheDir` | Cache files | `--cachedir` | `JELLYFIN_CACHE_DIR` |
|
|
| `LogDir` | Log files | `--logdir` | `JELLYFIN_LOG_DIR` |
|
|
| `TempDir` | Temporary files | `--tempdir` | `JELLYFIN_TEMP_DIR` |
|
|
| `WebDir` | Web client files | `--webdir` | `JELLYFIN_WEB_DIR` |
|
|
|
|
## Example Configurations
|
|
|
|
### Linux Production Server
|
|
|
|
```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"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Windows Production Server
|
|
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "C:\\ProgramData\\Jellyfin\\data",
|
|
"ConfigDir": "C:\\ProgramData\\Jellyfin\\config",
|
|
"CacheDir": "D:\\Cache\\Jellyfin",
|
|
"LogDir": "C:\\ProgramData\\Jellyfin\\logs",
|
|
"TempDir": "D:\\Temp\\Jellyfin",
|
|
"WebDir": "C:\\Program Files\\Jellyfin\\web"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Development Configuration
|
|
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "./dev-data",
|
|
"ConfigDir": "./dev-config",
|
|
"CacheDir": "./dev-cache",
|
|
"LogDir": "./dev-logs",
|
|
"TempDir": "./dev-temp",
|
|
"WebDir": "./wwwroot"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Minimal Configuration (Using Defaults)
|
|
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/custom/jellyfin/data"
|
|
}
|
|
}
|
|
```
|
|
|
|
In this example, only `DataDir` is overridden. All other paths will use their default values or environment variables.
|
|
|
|
### Partial Override with Environment Variables
|
|
|
|
**startup.json:**
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/var/lib/jellyfin",
|
|
"ConfigDir": "/etc/jellyfin"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Environment variables:**
|
|
```bash
|
|
export JELLYFIN_TEMP_DIR=/fast-storage/jellyfin-temp
|
|
```
|
|
|
|
**Result:** DataDir and ConfigDir come from the file, TempDir from environment variable, and all others use defaults.
|
|
|
|
## Use Cases
|
|
|
|
### 1. Containerized Deployments
|
|
|
|
**Docker Example:**
|
|
Create `startup.json` in your config volume:
|
|
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/data",
|
|
"ConfigDir": "/config",
|
|
"CacheDir": "/cache",
|
|
"LogDir": "/logs",
|
|
"TempDir": "/temp"
|
|
}
|
|
}
|
|
```
|
|
|
|
**docker-compose.yml:**
|
|
```yaml
|
|
version: '3.8'
|
|
services:
|
|
jellyfin:
|
|
image: jellyfin/jellyfin
|
|
volumes:
|
|
- ./startup.json:/config/startup.json
|
|
- jellyfin_data:/data
|
|
- jellyfin_cache:/cache
|
|
- jellyfin_logs:/logs
|
|
- jellyfin_temp:/temp
|
|
```
|
|
|
|
### 2. Multiple Instance Setup
|
|
|
|
Run multiple Jellyfin instances with different configurations:
|
|
|
|
**Instance 1 (startup-prod.json):**
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/srv/jellyfin/prod/data",
|
|
"ConfigDir": "/srv/jellyfin/prod/config",
|
|
"LogDir": "/srv/jellyfin/prod/logs"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Instance 2 (startup-test.json):**
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/srv/jellyfin/test/data",
|
|
"ConfigDir": "/srv/jellyfin/test/config",
|
|
"LogDir": "/srv/jellyfin/test/logs"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Portable Installation
|
|
|
|
Create a portable Jellyfin installation with relative paths:
|
|
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "./data",
|
|
"ConfigDir": "./config",
|
|
"CacheDir": "./cache",
|
|
"LogDir": "./logs",
|
|
"TempDir": "./temp",
|
|
"WebDir": "./web"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. Performance Optimization
|
|
|
|
Place different directories on different storage devices:
|
|
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/mnt/hdd/jellyfin/data",
|
|
"ConfigDir": "/mnt/ssd/jellyfin/config",
|
|
"CacheDir": "/mnt/ssd/jellyfin/cache",
|
|
"TempDir": "/mnt/nvme/jellyfin/temp",
|
|
"LogDir": "/mnt/hdd/jellyfin/logs"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Validation
|
|
|
|
When Jellyfin starts, it will log the configuration file being used:
|
|
|
|
```
|
|
Loaded startup configuration from: /path/to/startup.json
|
|
```
|
|
|
|
If the file has syntax errors, you'll see:
|
|
|
|
```
|
|
Warning: Failed to load startup configuration from /path/to/startup.json: [error message]
|
|
```
|
|
|
|
All resolved paths are logged at startup:
|
|
|
|
```
|
|
[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
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Configuration File Not Found
|
|
|
|
If your configuration file isn't being loaded:
|
|
|
|
1. Check the file is named exactly `startup.json`
|
|
2. Verify it's in one of the search locations
|
|
3. Check file permissions (must be readable)
|
|
4. Look for typos in the JSON structure
|
|
|
|
### Invalid JSON Syntax
|
|
|
|
Common JSON errors:
|
|
|
|
```json
|
|
// ❌ Wrong - trailing comma
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/var/lib/jellyfin",
|
|
}
|
|
}
|
|
|
|
// ✅ Correct
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/var/lib/jellyfin"
|
|
}
|
|
}
|
|
|
|
// ❌ Wrong - single quotes
|
|
{
|
|
"Paths": {
|
|
'DataDir': '/var/lib/jellyfin'
|
|
}
|
|
}
|
|
|
|
// ✅ Correct - double quotes
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/var/lib/jellyfin"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Path Resolution Order
|
|
|
|
Remember the priority:
|
|
1. CLI argument beats everything
|
|
2. Environment variable beats config file
|
|
3. Config file beats defaults
|
|
|
|
To test which source is being used, try setting different values in each and check the startup logs.
|
|
|
|
## Migration from Environment Variables
|
|
|
|
If you currently use environment variables, you can migrate to a config file:
|
|
|
|
**Before (environment variables):**
|
|
```bash
|
|
export JELLYFIN_DATA_DIR=/var/lib/jellyfin
|
|
export JELLYFIN_CONFIG_DIR=/etc/jellyfin
|
|
export JELLYFIN_CACHE_DIR=/var/cache/jellyfin
|
|
export JELLYFIN_LOG_DIR=/var/log/jellyfin
|
|
```
|
|
|
|
**After (startup.json):**
|
|
```json
|
|
{
|
|
"Paths": {
|
|
"DataDir": "/var/lib/jellyfin",
|
|
"ConfigDir": "/etc/jellyfin",
|
|
"CacheDir": "/var/cache/jellyfin",
|
|
"LogDir": "/var/log/jellyfin"
|
|
}
|
|
}
|
|
```
|
|
|
|
Then remove the environment variables from your `.bashrc`, systemd service, or wherever they're defined.
|
|
|
|
## Benefits
|
|
|
|
### Advantages of File-Based Configuration
|
|
|
|
1. **Portability**: Easy to copy configuration between systems
|
|
2. **Version Control**: Track configuration changes in Git
|
|
3. **Documentation**: Self-documenting with comments (in extended formats)
|
|
4. **Persistence**: Survives system reboots and shell sessions
|
|
5. **Consistency**: Same configuration across all instances
|
|
6. **No Shell Escaping**: No need to worry about shell quoting rules
|
|
7. **Easy Editing**: Simple text file, easy to modify
|
|
8. **Backup**: Can be backed up with other configuration files
|
|
|
|
### When to Use Each Method
|
|
|
|
| Method | Best For |
|
|
|--------|----------|
|
|
| **Config File** | Production servers, containers, permanent installations |
|
|
| **Environment Variables** | System-wide settings, CI/CD pipelines, user-specific overrides |
|
|
| **Command Line** | Testing, one-time overrides, debugging |
|
|
|
|
## Security Considerations
|
|
|
|
- Keep `startup.json` readable only by the Jellyfin user
|
|
- Don't commit sensitive paths to public repositories
|
|
- Use environment variables for secrets (like database passwords)
|
|
- Consider using separate config files per environment (dev/staging/prod)
|
|
|
|
## Example Setup Script
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# create-jellyfin-config.sh
|
|
|
|
cat > /etc/jellyfin/startup.json <<EOF
|
|
{
|
|
"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"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Set proper permissions
|
|
chmod 644 /etc/jellyfin/startup.json
|
|
chown jellyfin:jellyfin /etc/jellyfin/startup.json
|
|
|
|
echo "Jellyfin startup configuration created at /etc/jellyfin/startup.json"
|
|
```
|
|
|
|
## See Also
|
|
|
|
- [PATH_CONFIGURATION_GUIDE.md](PATH_CONFIGURATION_GUIDE.md) - Complete path configuration reference
|
|
- [startup.json.example](startup.json.example) - Template configuration file with JSON schema
|