Introduces automatic creation of a self-documenting startup.json file on first startup, with example path configurations for Linux, Windows, and portable setups. Adds preset database configurations to database.xml for easy switching between SQLite and PostgreSQL. Refactors database config classes for XML serialization compatibility and ensures database.xml is never empty. Comprehensive documentation and migration guides included.
12 KiB
Database Configuration Guide
Overview
Jellyfin's database configuration is stored in the database.xml file located in your configuration directory. This file is automatically created on first startup with SQLite as the default database provider.
As of this update, the configuration file includes preset configurations for both SQLite and PostgreSQL, making it easy to switch between database providers without having to remember all the configuration options.
Configuration File Location
The database.xml file is located in your Jellyfin configuration directory:
- Linux:
/etc/jellyfin/database.xmlor~/.config/jellyfin/database.xml - Windows:
%ProgramData%\Jellyfin\config\database.xml - Docker: Typically
/config/database.xmlin your config volume
Quick Start: Switching Between Databases
Method 1: Edit database.xml (Recommended)
-
Stop Jellyfin
# Linux sudo systemctl stop jellyfin # Windows net stop JellyfinServer # Docker docker stop jellyfin -
Edit database.xml
Change this line:
<DatabaseType>Jellyfin-SQLite</DatabaseType>To:
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType> -
Add PostgreSQL connection settings (uncomment and configure):
<CustomProviderOptions> <PluginName>Jellyfin.Database.Providers.Postgres</PluginName> <PluginAssembly>Jellyfin.Database.Providers.Postgres.dll</PluginAssembly> <ConnectionString></ConnectionString> <Options> <CustomDatabaseOption> <Key>host</Key> <Value>localhost</Value> </CustomDatabaseOption> <CustomDatabaseOption> <Key>port</Key> <Value>5432</Value> </CustomDatabaseOption> <CustomDatabaseOption> <Key>database</Key> <Value>jellyfin</Value> </CustomDatabaseOption> <CustomDatabaseOption> <Key>username</Key> <Value>jellyfin</Value> </CustomDatabaseOption> <CustomDatabaseOption> <Key>password</Key> <Value>your_secure_password</Value> </CustomDatabaseOption> </Options> </CustomProviderOptions> -
Start Jellyfin
sudo systemctl start jellyfin
Method 2: Use Preset Configurations
The database.xml file now includes preset configurations that serve as templates. These presets show you exactly what settings are needed for each database type.
Available Presets:
SQLite- Default single-file databasePostgreSQL-Local- PostgreSQL on localhost
To use a preset:
- Look at the preset configuration in the
<PresetConfigurations>section - Copy the settings to the active configuration at the top of the file
- Configure any additional options (like PostgreSQL credentials)
Configuration File Structure
<?xml version="1.0" encoding="utf-8"?>
<DatabaseConfigurationOptions>
<!-- ACTIVE CONFIGURATION -->
<DatabaseType>Jellyfin-SQLite</DatabaseType>
<LockingBehavior>NoLock</LockingBehavior>
<!-- POSTGRESQL OPTIONS (when using PostgreSQL) -->
<CustomProviderOptions>
<!-- PostgreSQL connection settings -->
</CustomProviderOptions>
<!-- BACKUP SETTINGS -->
<BackupOptions>
<EnableAutoBackup>false</EnableAutoBackup>
<BackupRetentionDays>30</BackupRetentionDays>
</BackupOptions>
<!-- PRESET CONFIGURATIONS (Templates) -->
<PresetConfigurations>
<!-- SQLite and PostgreSQL presets -->
</PresetConfigurations>
</DatabaseConfigurationOptions>
Configuration Properties
DatabaseType
The active database provider to use.
Options:
Jellyfin-SQLite- Use SQLite database (default)Jellyfin-PostgreSQL- Use PostgreSQL database
Example:
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
LockingBehavior
How Jellyfin should handle database locking.
Options:
NoLock- No locking (recommended for most installations)Pessimistic- Lock rows before readingOptimistic- Check for conflicts after reading
Default: NoLock
Example:
<LockingBehavior>NoLock</LockingBehavior>
CustomProviderOptions
Connection settings for PostgreSQL (not needed for SQLite).
Required Properties:
PluginName- Always set toJellyfin.Database.Providers.PostgresPluginAssembly- Always set toJellyfin.Database.Providers.Postgres.dllConnectionString- Leave empty (connection built from Options)Options- List of key-value pairs for connection settings
PostgreSQL Options:
| Key | Description | Default | Example |
|---|---|---|---|
host |
PostgreSQL server hostname | localhost |
localhost, 192.168.1.100, db.example.com |
port |
PostgreSQL server port | 5432 |
5432 |
database |
Database name | jellyfin |
jellyfin, jellyfin_prod |
username |
Database username | jellyfin |
jellyfin, postgres |
password |
Database password | (empty) | your_secure_password |
connection-timeout |
Connection timeout in seconds | 15 |
15, 30 |
Example:
<CustomProviderOptions>
<PluginName>Jellyfin.Database.Providers.Postgres</PluginName>
<PluginAssembly>Jellyfin.Database.Providers.Postgres.dll</PluginAssembly>
<ConnectionString></ConnectionString>
<Options>
<CustomDatabaseOption>
<Key>host</Key>
<Value>localhost</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>port</Key>
<Value>5432</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>database</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>username</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>password</Key>
<Value>MySecurePassword123</Value>
</CustomDatabaseOption>
</Options>
</CustomProviderOptions>
BackupOptions
Configure automatic database backups (optional).
Properties:
EnableAutoBackup- Enable/disable automatic backupsBackupRetentionDays- How many days to keep backups
Example:
<BackupOptions>
<EnableAutoBackup>true</EnableAutoBackup>
<BackupRetentionDays>30</BackupRetentionDays>
</BackupOptions>
PresetConfigurations
Template configurations for quick reference. These are NOT active configurations - they're just examples stored in the file for your convenience.
Complete Examples
Example 1: SQLite Configuration
<?xml version="1.0" encoding="utf-8"?>
<DatabaseConfigurationOptions>
<DatabaseType>Jellyfin-SQLite</DatabaseType>
<LockingBehavior>NoLock</LockingBehavior>
<BackupOptions>
<EnableAutoBackup>false</EnableAutoBackup>
<BackupRetentionDays>30</BackupRetentionDays>
</BackupOptions>
<PresetConfigurations>
<!-- Presets stored here for reference -->
</PresetConfigurations>
</DatabaseConfigurationOptions>
Example 2: PostgreSQL Configuration (Localhost)
<?xml version="1.0" encoding="utf-8"?>
<DatabaseConfigurationOptions>
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
<LockingBehavior>NoLock</LockingBehavior>
<CustomProviderOptions>
<PluginName>Jellyfin.Database.Providers.Postgres</PluginName>
<PluginAssembly>Jellyfin.Database.Providers.Postgres.dll</PluginAssembly>
<ConnectionString></ConnectionString>
<Options>
<CustomDatabaseOption>
<Key>host</Key>
<Value>localhost</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>port</Key>
<Value>5432</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>database</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>username</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>password</Key>
<Value>YourSecurePassword</Value>
</CustomDatabaseOption>
</Options>
</CustomProviderOptions>
<BackupOptions>
<EnableAutoBackup>true</EnableAutoBackup>
<BackupRetentionDays>30</BackupRetentionDays>
</BackupOptions>
</DatabaseConfigurationOptions>
Example 3: PostgreSQL Configuration (Remote Server)
<?xml version="1.0" encoding="utf-8"?>
<DatabaseConfigurationOptions>
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
<LockingBehavior>NoLock</LockingBehavior>
<CustomProviderOptions>
<PluginName>Jellyfin.Database.Providers.Postgres</PluginName>
<PluginAssembly>Jellyfin.Database.Providers.Postgres.dll</PluginAssembly>
<ConnectionString></ConnectionString>
<Options>
<CustomDatabaseOption>
<Key>host</Key>
<Value>db.example.com</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>port</Key>
<Value>5432</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>database</Key>
<Value>jellyfin_production</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>username</Key>
<Value>jellyfin_user</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>password</Key>
<Value>VerySecurePassword123!</Value>
</CustomDatabaseOption>
<CustomDatabaseOption>
<Key>connection-timeout</Key>
<Value>30</Value>
</CustomDatabaseOption>
</Options>
</CustomProviderOptions>
<BackupOptions>
<EnableAutoBackup>true</EnableAutoBackup>
<BackupRetentionDays>7</BackupRetentionDays>
</BackupOptions>
</DatabaseConfigurationOptions>
Migration Between Databases
From SQLite to PostgreSQL
-
Backup your current SQLite database
cp jellyfin.db jellyfin.db.backup -
Set up PostgreSQL server and create database
CREATE DATABASE jellyfin; CREATE USER jellyfin WITH PASSWORD 'your_password'; GRANT ALL PRIVILEGES ON DATABASE jellyfin TO jellyfin; -
Stop Jellyfin
-
Edit database.xml to use PostgreSQL (see examples above)
-
Start Jellyfin - Migrations will run automatically
-
Note: This creates a fresh database. To migrate data, you'll need to use Jellyfin's backup/restore features or export/import your library.
From PostgreSQL to SQLite
-
Stop Jellyfin
-
Edit database.xml - Change DatabaseType to
Jellyfin-SQLiteand remove CustomProviderOptions -
Start Jellyfin - A new SQLite database will be created
-
Note: Data migration requires backup/restore or manual export/import
Troubleshooting
Configuration not taking effect
Solution: Ensure you've stopped Jellyfin before editing the configuration file, and that the file is saved with proper XML formatting.
PostgreSQL connection fails
Check:
- PostgreSQL server is running:
sudo systemctl status postgresql - Database exists:
psql -l - User has permissions:
psql -U jellyfin -d jellyfin - Firewall allows connection on port 5432
- Password is correct in database.xml
Cannot find database.xml
Solution: The file is created on first startup. If missing:
- Start Jellyfin once to generate it
- Or copy from
database.xml.examplein the source repository
Preset configurations not working
Important: Presets are templates only! They don't activate automatically. You must:
- Copy the DatabaseType from the preset to the active configuration
- Add CustomProviderOptions if needed for PostgreSQL
- Configure the actual connection settings
Security Considerations
-
Protect database.xml - It contains passwords
chmod 600 /etc/jellyfin/database.xml chown jellyfin:jellyfin /etc/jellyfin/database.xml -
Use strong PostgreSQL passwords
-
Restrict network access to PostgreSQL server
-
Enable automatic backups for production systems
-
Don't commit database.xml to version control with real passwords
See Also
- FILE_BASED_STARTUP_CONFIG.md - Path configuration
- TROUBLESHOOTING_EF_PENDING_CHANGES.md - Database migration issues
- startup.json.example - Path configuration template
- database.xml.example - Database configuration template