# Jellyfin with PostgreSQL Support This is a fork of Jellyfin that adds PostgreSQL database support for .NET 11 preview. ## Features - ✅ PostgreSQL database provider implementation - ✅ Automatic database initialization from SQL scripts - ✅ Remote database support with connection string configuration - ✅ Database backup/restore via pg_dump/pg_restore - ✅ Migration system disabled in favor of SQL scripts - ✅ Support for both local and remote PostgreSQL servers --- ## Requirements ### FFmpeg Requirements **jellyfin-ffmpeg is highly preferred and recommended** for use with Jellyfin Media Server. While standard FFmpeg can be used, the custom `jellyfin-ffmpeg` fork includes specifically targeted fixes, optimizations, and enhanced hardware acceleration support for media streaming that may not be available or prioritized in the upstream version. #### Why jellyfin-ffmpeg is Preferred: - **Improved Hardware Acceleration**: Better support for hardware acceleration (NVENC, QuickSync, VA-API) across a wider range of GPUs, reducing the risk of partial acceleration - **Reduced Playback Issues**: Specifically built to handle HDR/Dolby Vision content, HLS/fMP4/MPEG-TS streaming, and complex transcoding scenarios better than standard FFmpeg - **Optimized Performance**: Often includes more efficient software decoders (like dav1d for AV1) - **Pre-configured**: Automatically included with official Docker images, deb packages, and Windows installers **Link**: [jellyfin-ffmpeg repository](https://github.com/jellyfin/jellyfin-ffmpeg) #### Installation: **Debian/Ubuntu** (using Jellyfin repository): ```bash # Add Jellyfin repository (if not already added) sudo apt-get install -y software-properties-common sudo add-apt-repository universe # Install jellyfin-ffmpeg sudo apt-get update sudo apt-get install -y jellyfin-ffmpeg6 ``` **Manual Download**: Download from [jellyfin-ffmpeg releases](https://github.com/jellyfin/jellyfin-ffmpeg/releases) and configure the path in Jellyfin settings. #### Using Standard FFmpeg (Not Recommended): If using a custom or unofficial installation where jellyfin-ffmpeg is not available, standard FFmpeg might work but could lead to issues with specific transcoding tasks: ```bash # Debian/Ubuntu sudo apt-get install -y ffmpeg # RHEL/Fedora sudo dnf install -y ffmpeg # Arch Linux sudo pacman -S ffmpeg ``` **Note**: You may need to manually set the FFmpeg path in Jellyfin's dashboard under **Dashboard → Playback → FFmpeg path**. ### System Dependencies (Linux) Jellyfin requires certain system libraries to be installed: #### Debian/Ubuntu-based systems: ```bash sudo apt-get update sudo apt-get install -y \ libfontconfig1 \ libfreetype6 \ libssl3 \ libicu-dev ``` **Note**: See the [FFmpeg Requirements](#ffmpeg-requirements) section above for installing `jellyfin-ffmpeg`. #### RHEL/CentOS/Fedora-based systems: ```bash sudo dnf install -y \ fontconfig \ freetype \ openssl \ libicu ``` **Note**: See the [FFmpeg Requirements](#ffmpeg-requirements) section above for installing FFmpeg. #### Arch Linux: ```bash sudo pacman -S fontconfig freetype2 openssl icu ``` **Note**: See the [FFmpeg Requirements](#ffmpeg-requirements) section above for installing FFmpeg. **Note**: The `libfontconfig1` library is **required** for SkiaSharp (image processing). Without it, Jellyfin will fail to start with: ``` libfontconfig.so.1: cannot open shared object file: No such file or directory ``` ### PostgreSQL Requirements - PostgreSQL 12 or higher (tested with PostgreSQL 18.3) - `psql` client tools (for automatic schema initialization) - Network access to PostgreSQL server (if using remote database) #### Install PostgreSQL client tools: **Debian/Ubuntu**: ```bash sudo apt-get install -y postgresql-client ``` **RHEL/CentOS/Fedora**: ```bash sudo dnf install -y postgresql ``` **Verify psql is available**: ```bash psql --version ``` --- ## Database Configuration ### Option 1: Using ConnectionString (Recommended) Create or edit `config/database.xml` in your Jellyfin data directory: ```xml Jellyfin-PostgreSQL NoLock Jellyfin-PostgreSQL Jellyfin.Database.Providers.Postgres Host=192.168.1.100;Port=5432;Database=jellyfin;Username=jellyfin;Password=your_password_here pg_dump pg_restore custom true 6 1800 true ``` ### Option 2: Using Individual Options ```xml Jellyfin-PostgreSQL Jellyfin-PostgreSQL Jellyfin.Database.Providers.Postgres Host 192.168.1.100 Port 5432 Database jellyfin Username jellyfin Password your_password_here ``` ### Option 3: Hybrid (ConnectionString + Overrides) Individual options take precedence over ConnectionString: ```xml Host=192.168.1.100;Port=5432;Database=jellyfin;Username=jellyfin Password production_password ``` --- ## Database Initialization ### Automatic Initialization When Jellyfin starts with an empty database: 1. **Database Check**: Checks if the database exists (creates if missing) 2. **Table Check**: Checks if `users.Users` table exists 3. **Auto-Initialize**: If tables don't exist, automatically runs `sql/schema_init/create_database_schema.sql` via `psql` 4. **Schema Verification**: Verifies all required schemas and tables are present **Requirements for automatic initialization**: - ✅ `psql` command must be in system PATH - ✅ Database must exist (created automatically or manually) - ✅ SQL script must be deployed: `sql/schema_init/create_database_schema.sql` ### Manual Initialization If `psql` is not available or automatic initialization fails: ```bash # Create database first createdb -U postgres jellyfin # Run schema creation script psql -U postgres -d jellyfin -f /path/to/jellyfin/sql/schema_init/create_database_schema.sql ``` --- ## Startup Logs ### Successful Startup (Empty Database): ``` [INF] PostgreSQL connection: Host="192.168.1.100", Port=5432, Database="jellyfin", ... [INF] Database tables not found (users.Users table missing). Initializing from SQL script... [INF] Found schema script at: .../sql/schema_init/create_database_schema.sql [INF] Executing create_database_schema.sql (this may take several minutes)... [INF] Executing via psql: psql -h 192.168.1.100 -p 5432 -U jellyfin -d jellyfin -f "..." [INF] ✅ Successfully initialized database from SQL script via psql [INF] Database is ready. You can now start Jellyfin. [DBG] Schema 'users' contains 4 tables [DBG] Schema 'library' contains 45 tables [DBG] Schema 'activitylog' contains 1 tables [INF] ✅ Database schema verification complete [INF] There are 0 migrations for stage CoreInitialisation [INF] There are 24 migrations for stage AppInitialisation ``` ### Successful Startup (Existing Database): ``` [INF] PostgreSQL connection: Host="192.168.1.100", Port=5432, Database="jellyfin", ... [INF] Database tables exist (users.Users table found) [DBG] Schema 'users' contains 4 tables [DBG] Schema 'library' contains 45 tables [INF] ✅ Database schema verification complete ``` --- ## Troubleshooting ### Error: `libfontconfig.so.1: cannot open shared object file` **Cause**: Missing system dependency **Solution**: ```bash # Debian/Ubuntu sudo apt-get install -y libfontconfig1 # RHEL/Fedora sudo dnf install -y fontconfig ``` ### Error: `psql command not found` **Cause**: PostgreSQL client tools not installed **Solution**: ```bash # Debian/Ubuntu sudo apt-get install -y postgresql-client # RHEL/Fedora sudo dnf install -y postgresql ``` ### Error: `Failed to connect to 127.0.0.1:5432` **Cause**: Configuration not loading correctly (using default localhost) **Solution**: - Verify `database.xml` is in the correct location (`/var/lib/jellyfin/config/database.xml` on Linux) - Check that ConnectionString or individual Options are properly configured - Ensure Host is set to your remote server IP/hostname ### Error: `database "jellyfin" does not exist` **Cause**: Database wasn't created automatically (rare) **Solution**: ```bash # Create database manually createdb -U postgres -h your-server jellyfin # Grant privileges psql -U postgres -h your-server -c "GRANT ALL PRIVILEGES ON DATABASE jellyfin TO jellyfin;" # Restart Jellyfin (it will create tables automatically) ``` --- ## Architecture ### Database Schema - `activitylog` - Activity log entries - `authentication` - API keys, devices, device options - `displaypreferences` - User display preferences - `library` - Media library data (BaseItems, metadata, etc.) - `users` - User accounts, permissions, preferences ### Migration System **Entity Framework migrations are DISABLED** for .NET 11 preview. Schema changes are managed via SQL scripts: - **Core migrations**: Disabled (no database structure changes via EF) - **Application migrations**: Enabled (configuration and data migrations only) **Why**: EF migrations in preview builds can cause schema inconsistencies. SQL scripts provide reliable schema management. --- ## Backup and Restore ### Automatic Backups (via pg_dump) Configured in `database.xml`: ```xml pg_dump custom 6 ``` **Works for both local and remote databases!** ### Manual Backup ```bash # Backup to custom format (compressed) pg_dump -h your-server -U jellyfin -d jellyfin -Fc -f jellyfin_backup.dump # Backup to SQL format pg_dump -h your-server -U jellyfin -d jellyfin -f jellyfin_backup.sql ``` ### Manual Restore ```bash # Restore from custom format pg_restore -h your-server -U jellyfin -d jellyfin jellyfin_backup.dump # Restore from SQL format psql -h your-server -U jellyfin -d jellyfin -f jellyfin_backup.sql ``` --- ## Troubleshooting Connection Issues ### Error: `57P01: terminating connection due to administrator command` **Cause**: PostgreSQL server forcibly terminated the connection during an operation **Common reasons**: - PostgreSQL server restart or reload - Connection timeout (statement_timeout, idle_in_transaction_session_timeout) - Manual connection termination via `pg_terminate_backend()` - Network instability or firewall issues - Resource limits exceeded (max_connections, memory pressure) **Solutions**: #### 1. Configure Automatic Retry (Already Enabled) Jellyfin now includes automatic retry logic for transient failures: - **Max retries**: 3 attempts - **Max delay**: 5 seconds between retries - **Retryable errors**: Includes `57P01` (connection termination) #### 2. Increase PostgreSQL Timeouts Edit PostgreSQL configuration (`/etc/postgresql/*/main/postgresql.conf`): ``` # Increase statement timeout statement_timeout = 300000 # 5 minutes (in milliseconds) # Increase idle transaction timeout idle_in_transaction_session_timeout = 600000 # 10 minutes # Enable TCP keepalives (prevent network timeouts) tcp_keepalives_idle = 60 # seconds tcp_keepalives_interval = 10 # seconds tcp_keepalives_count = 6 ``` Reload PostgreSQL: ```bash sudo systemctl reload postgresql # OR psql -U postgres -c "SELECT pg_reload_conf();" ``` #### 3. Optimize Connection String Add keepalive and timeout parameters to your connection string: ```xml Host=192.168.129.253;Port=5432;Database=jellyfin;Username=jellyfin;Password=yourpass;Pooling=True;Minimum Pool Size=0;Maximum Pool Size=50;Connection Idle Lifetime=300;Connection Pruning Interval=10;Timeout=30;Command Timeout=300;Keepalive=60 ``` **Key parameters**: - `Timeout=30` - Connection establishment timeout (30 seconds) - `Command Timeout=300` - Query execution timeout (5 minutes) - `Keepalive=60` - TCP keepalive interval (60 seconds) - `Connection Idle Lifetime=300` - Close idle connections after 5 minutes - `Connection Pruning Interval=10` - Check for stale connections every 10 seconds #### 4. Check PostgreSQL Logs On your PostgreSQL server: ```bash # View recent logs sudo tail -f /var/log/postgresql/postgresql-*.log # Or check systemd journal sudo journalctl -u postgresql -n 100 --no-pager ``` Look for: - `received fast shutdown request` - `terminating connection` - `too many connections` - `out of memory` #### 5. Monitor Active Connections ```sql -- Check current connections SELECT datname, usename, application_name, state, state_change FROM pg_stat_activity WHERE datname = 'jellyfin' ORDER BY state_change DESC; -- Check connection limits SELECT (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections, (SELECT COUNT(*) FROM pg_stat_activity) AS current_connections, (SELECT COUNT(*) FROM pg_stat_activity WHERE datname = 'jellyfin') AS jellyfin_connections; ``` --- ## Building from Source ```bash # Clone repository git clone https://github.com/yourusername/jellyfin.git cd jellyfin # Checkout the upgrade branch git checkout upgrade-to-NET11 # Build dotnet build # Run cd Jellyfin.Server dotnet run ``` --- ## Contributing This is a development/preview branch. For production use, please use the official Jellyfin releases. ## License GNU General Public License v2.0 (same as Jellyfin) --- ## Credits Based on [Jellyfin](https://github.com/jellyfin/jellyfin) with PostgreSQL support and .NET 11 compatibility.