# Publishing Profiles for Multi-Instance Jellyfin ## Overview Three publishing profiles have been created for deploying your multi-instance PostgreSQL-enabled Jellyfin: 1. **MultiInstance-Win-x64** - Self-contained Windows deployment 2. **MultiInstance-Linux-x64** - Self-contained Linux deployment 3. **MultiInstance-FrameworkDependent** - Smaller deployment requiring .NET 11 runtime ## Publishing Profiles ### 1. MultiInstance-Win-x64 (Recommended for Windows) **Best for**: Windows production deployments **Features**: - ✅ Self-contained (includes .NET 11 runtime) - ✅ Windows x64 optimized - ✅ ReadyToRun compilation (faster startup) - ✅ Includes SQL scripts for multi-instance setup - ✅ Includes documentation **Output**: `Jellyfin.Server\bin\Publish\MultiInstance-Win-x64\` **Usage**: ```powershell # Command line dotnet publish Jellyfin.Server\Jellyfin.Server.csproj -p:PublishProfile=MultiInstance-Win-x64 # Or from Visual Studio: # Right-click Jellyfin.Server project → Publish → MultiInstance-Win-x64 ``` ### 2. MultiInstance-Linux-x64 (Recommended for Linux) **Best for**: Linux production deployments **Features**: - ✅ Self-contained (includes .NET 11 runtime) - ✅ Linux x64 optimized - ✅ ReadyToRun compilation (faster startup) - ✅ Includes SQL scripts and documentation **Output**: `Jellyfin.Server\bin\Publish\MultiInstance-Linux-x64\` **Usage**: ```powershell # Command line dotnet publish Jellyfin.Server\Jellyfin.Server.csproj -p:PublishProfile=MultiInstance-Linux-x64 # On Linux: chmod +x ./jellyfin ./jellyfin ``` ### 3. MultiInstance-FrameworkDependent **Best for**: Environments with .NET 11 runtime pre-installed **Features**: - ✅ Smaller deployment size (~100MB vs ~150MB for self-contained) - ✅ Requires .NET 11 runtime on target system - ✅ Faster deployment/transfer - ✅ Centralized runtime management **Output**: `Jellyfin.Server\bin\Publish\MultiInstance-FrameworkDependent\` **Prerequisites**: Target system must have .NET 11 runtime installed: ```powershell # Check if .NET 11 is installed dotnet --list-runtimes | Select-String "Microsoft.NETCore.App 11" # Install if missing # Download from: https://dotnet.microsoft.com/download/dotnet/11.0 ``` **Usage**: ```powershell dotnet publish Jellyfin.Server\Jellyfin.Server.csproj -p:PublishProfile=MultiInstance-FrameworkDependent ``` ## What Gets Published All profiles include: ### Core Application - ✅ `jellyfin.exe` (Windows) or `jellyfin` (Linux) - ✅ All .NET assemblies and dependencies - ✅ Npgsql provider for PostgreSQL - ✅ Multi-instance clustering code (Phases 1-6) ### Configuration Files - ✅ `startup.json.windows` - Windows configuration template - ✅ `startup.json.linux` - Linux configuration template - ✅ `appsettings.json` - Application settings ### SQL Scripts - ✅ `sql/add_multi_instance_support.sql` - Complete multi-instance setup - ✅ All database migration scripts ### Documentation - ✅ `docs/MULTI_INSTANCE_COMPLETE.md` - Complete implementation guide - ✅ `docs/PHASE5_PRIMARY_ELECTION_COMPLETE.md` - Primary election details - ✅ `docs/PHASE6_FILESYSTEM_COORDINATION_COMPLETE.md` - File system coordination - ✅ `docs/POSTGRESQL_CONNECTION_TROUBLESHOOTING.md` - Connection troubleshooting ### Web Client - ✅ `wwwroot/` - Jellyfin web interface files ## Deployment Workflow ### Step 1: Choose Your Profile ```powershell # For Windows production server $profile = "MultiInstance-Win-x64" # For Linux production server $profile = "MultiInstance-Linux-x64" # For server with .NET 11 runtime installed $profile = "MultiInstance-FrameworkDependent" ``` ### Step 2: Publish ```powershell # From project root cd D:\Projects\pgsql-jellyfin # Clean previous builds dotnet clean Jellyfin.Server\Jellyfin.Server.csproj --configuration Release # Publish dotnet publish Jellyfin.Server\Jellyfin.Server.csproj ` -p:PublishProfile=$profile ` --configuration Release ``` ### Step 3: Verify Output ```powershell # Check publish directory $publishDir = "Jellyfin.Server\bin\Publish\$profile" Get-ChildItem $publishDir # Verify critical files exist Test-Path "$publishDir\jellyfin.exe" # Windows Test-Path "$publishDir\sql\add_multi_instance_support.sql" Test-Path "$publishDir\docs\MULTI_INSTANCE_COMPLETE.md" ``` ### Step 4: Deploy to Server **Option A: Copy to Local Path** ```powershell $deployPath = "C:\Program Files\Jellyfin-MultiInstance" Copy-Item -Path "$publishDir\*" -Destination $deployPath -Recurse -Force ``` **Option B: Copy to Network Share** ```powershell $networkPath = "\\server\share\Jellyfin" Copy-Item -Path "$publishDir\*" -Destination $networkPath -Recurse -Force ``` **Option C: Package for Transfer** ```powershell # Create ZIP archive $version = "multi-instance-$(Get-Date -Format 'yyyyMMdd')" Compress-Archive -Path "$publishDir\*" ` -DestinationPath "Jellyfin-$version.zip" ` -Force ``` ### Step 5: Configure on Target Server 1. **Create `database.xml`** in config directory: ```xml Jellyfin-PostgreSQL Host=YOUR_PG_SERVER;Port=5432;Database=jellyfin;Username=jellyfin;Password=YOUR_PASSWORD ``` 2. **Run multi-instance SQL** (first deployment only): ```powershell psql -h YOUR_PG_SERVER -U jellyfin -d jellyfin -f sql\add_multi_instance_support.sql ``` 3. **Start Jellyfin**: ```powershell # Windows .\jellyfin.exe # Linux ./jellyfin ``` ## Visual Studio Publishing ### Method 1: Using Solution Explorer 1. **Right-click** `Jellyfin.Server` project 2. Click **Publish** 3. Select one of the multi-instance profiles: - MultiInstance-Win-x64 - MultiInstance-Linux-x64 - MultiInstance-FrameworkDependent 4. Click **Publish** ### Method 2: Using Publish Dialog 1. **Build** → **Publish Jellyfin.Server** 2. Choose **Folder** target 3. Select existing profile from dropdown 4. Click **Publish** ## Continuous Deployment ### PowerShell Script ```powershell # PublishAndDeploy.ps1 param( [string]$Profile = "MultiInstance-Win-x64", [string]$DeployPath = "C:\Program Files\Jellyfin-MultiInstance", [switch]$SkipDeploy ) # Publish Write-Host "Publishing with profile: $Profile" -ForegroundColor Cyan dotnet publish Jellyfin.Server\Jellyfin.Server.csproj ` -p:PublishProfile=$Profile ` --configuration Release if ($LASTEXITCODE -ne 0) { Write-Error "Publish failed!" exit 1 } $publishDir = "Jellyfin.Server\bin\Publish\$Profile" # Verify Write-Host "Verifying publish output..." -ForegroundColor Cyan if (-not (Test-Path "$publishDir\jellyfin.exe")) { Write-Error "jellyfin.exe not found in publish output!" exit 1 } # Deploy if (-not $SkipDeploy) { Write-Host "Deploying to: $DeployPath" -ForegroundColor Cyan # Stop existing service if running Get-Process -Name "jellyfin" -ErrorAction SilentlyContinue | Stop-Process -Force # Copy files Copy-Item -Path "$publishDir\*" -Destination $DeployPath -Recurse -Force Write-Host "Deployment complete!" -ForegroundColor Green } else { Write-Host "Skipping deployment (use -SkipDeploy:`$false to deploy)" -ForegroundColor Yellow } Write-Host "Publish directory: $publishDir" -ForegroundColor Green ``` **Usage**: ```powershell # Publish and deploy to default location .\PublishAndDeploy.ps1 # Publish for Linux (no deployment) .\PublishAndDeploy.ps1 -Profile MultiInstance-Linux-x64 -SkipDeploy # Publish and deploy to custom location .\PublishAndDeploy.ps1 -Profile MultiInstance-Win-x64 -DeployPath "D:\Jellyfin" ``` ## Deployment Sizes | Profile | Approximate Size | .NET Runtime | Startup Speed | |---------|------------------|--------------|---------------| | Win-x64 (Self-Contained) | ~150MB | ✅ Included | Fast (ReadyToRun) | | Linux-x64 (Self-Contained) | ~150MB | ✅ Included | Fast (ReadyToRun) | | Framework-Dependent | ~100MB | ❌ Required on target | Normal | ## Multi-Instance Deployment ### Scenario: 2 Instances on Same Server **Instance 1**: ```powershell # Deploy to first location $instance1 = "C:\Jellyfin-Instance1" Copy-Item -Path "Jellyfin.Server\bin\Publish\MultiInstance-Win-x64\*" ` -Destination $instance1 -Recurse -Force # Create config with custom port # startup.json → port: 8096 # database.xml → Host=192.168.129.248;Database=jellyfin ``` **Instance 2**: ```powershell # Deploy to second location $instance2 = "C:\Jellyfin-Instance2" Copy-Item -Path "Jellyfin.Server\bin\Publish\MultiInstance-Win-x64\*" ` -Destination $instance2 -Recurse -Force # Create config with different port # startup.json → port: 8097 # database.xml → SAME PostgreSQL connection (192.168.129.248) ``` **Both instances will**: - ✅ Connect to the same PostgreSQL database - ✅ Register as separate instances - ✅ Coordinate via distributed locks - ✅ Share cache invalidations - ✅ Elect primary for scheduled tasks ## Troubleshooting ### Publish Fails **Check .NET SDK version**: ```powershell dotnet --version # Should be 11.x or newer ``` **Clean and retry**: ```powershell dotnet clean --configuration Release dotnet publish -p:PublishProfile=MultiInstance-Win-x64 ``` ### Missing SQL Scripts in Output The profiles include explicit `` entries to copy SQL files. Verify they exist: ```powershell Get-ChildItem -Path "sql\*.sql" -Recurse ``` ### Published App Won't Start **Check database.xml location**: ```powershell # Should be in config directory specified by startup.json Get-Content "C:\Program Files\Jellyfin-MultiInstance\startup.json" | ConvertFrom-Json | Select-Object -ExpandProperty Paths ``` **Test PostgreSQL connection**: ```powershell Test-NetConnection -ComputerName 192.168.129.248 -Port 5432 ``` ## Related Documentation - 📄 `docs/MULTI_INSTANCE_COMPLETE.md` - Complete multi-instance overview - 📄 `docs/CONFIGURATION_LOADING_FIX.md` - How configuration loading works - 📄 `docs/POSTGRESQL_CONNECTION_TROUBLESHOOTING.md` - Connection issues ## Summary ✅ **Created 3 publishing profiles**: - `MultiInstance-Win-x64.pubxml` - Windows self-contained - `MultiInstance-Linux-x64.pubxml` - Linux self-contained - `MultiInstance-FrameworkDependent.pubxml` - Smaller, requires runtime ✅ **All profiles include**: - Multi-instance code (all 6 phases) - SQL setup scripts - Configuration templates - Documentation ✅ **Ready to use**: ```powershell dotnet publish -p:PublishProfile=MultiInstance-Win-x64 ``` --- **Status**: ✅ Publishing profiles ready **Next**: Publish and deploy to your servers!