77e30685bb
- Implements Phases 3–6: session isolation, cache coordination, primary election, and file system monitor coordination for Jellyfin with PostgreSQL. - Adds new database entities (Instance, DistributedLock, FileSystemChange) and EF model configurations. - Includes SQL migration scripts and EF migration for all required tables, columns, and helper functions. - Updates Device entity and JellyfinDbContext for multi-instance tracking. - Integrates new DI services for instance registry, distributed locks, cache coordinator, and primary election. - Adds publishing profiles (Win/Linux/FrameworkDependent) and automation script for deployment. - Extensive documentation for architecture, setup, and publishing. - All changes are backward compatible and build successfully.
393 lines
10 KiB
Markdown
393 lines
10 KiB
Markdown
# 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
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
<DatabaseConfigurationOptions>
|
|
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
|
|
<CustomProviderOptions>
|
|
<ConnectionString>Host=YOUR_PG_SERVER;Port=5432;Database=jellyfin;Username=jellyfin;Password=YOUR_PASSWORD</ConnectionString>
|
|
</CustomProviderOptions>
|
|
</DatabaseConfigurationOptions>
|
|
```
|
|
|
|
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 `<ItemGroup>` 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!
|