# 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!