c51c14efde
- Rewrote README.md to highlight PostgreSQL features, installer, and migration, with quick start and full docs index - Moved all markdown documentation files to docs/ for better organization; updated links accordingly - Added .gitignore rules to exclude all PublishProfiles folders; removed tracked publish profile XMLs - Preserved original README as README.original.md; added README_GENERATION.md and DOCUMENTATION_ORGANIZATION.md - Cleaned root directory, improved navigation, and clarified platform-specific instructions
591 lines
15 KiB
Markdown
591 lines
15 KiB
Markdown
# Creating an Installer for Jellyfin
|
|
|
|
**Solution:** E:\Projects\pgsql-jellyfin
|
|
**Target:** Windows Installer for PostgreSQL-enabled Jellyfin
|
|
**Status:** Guide for implementation
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
You can create professional installers for your Jellyfin solution using several methods. Here are your options ranked by recommendation:
|
|
|
|
---
|
|
|
|
## ✅ Recommended: WiX Toolset (Best for Windows)
|
|
|
|
### Why WiX?
|
|
- ✅ Industry standard for .NET applications
|
|
- ✅ Creates proper MSI installers
|
|
- ✅ Full Windows Installer features (services, registry, shortcuts)
|
|
- ✅ Supports upgrades and uninstalls
|
|
- ✅ Free and open source
|
|
- ✅ Integrates with Visual Studio
|
|
|
|
### Prerequisites
|
|
```powershell
|
|
# Install WiX Toolset
|
|
winget install --id WiX.Toolset
|
|
|
|
# Or download from:
|
|
# https://wixtoolset.org/
|
|
```
|
|
|
|
### Implementation Steps
|
|
|
|
#### Step 1: Create WiX Project
|
|
|
|
Add to your solution:
|
|
```xml
|
|
<!-- Jellyfin.Installer.csproj -->
|
|
<Project Sdk="WixToolset.Sdk/5.0.0">
|
|
<PropertyGroup>
|
|
<OutputType>Package</OutputType>
|
|
<Platform>x64</Platform>
|
|
<TargetFramework>net11.0</TargetFramework>
|
|
<OutputName>JellyfinSetup-PostgreSQL-$(Version)</OutputName>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup>
|
|
<!-- Reference the main Jellyfin.Server project -->
|
|
<ProjectReference Include="..\Jellyfin.Server\Jellyfin.Server.csproj">
|
|
<Private>true</Private>
|
|
<DoNotHarvest>true</DoNotHarvest>
|
|
<IncludeOutputGroupInVSIXContainer>true</IncludeOutputGroupInVSIXContainer>
|
|
</ProjectReference>
|
|
</ItemGroup>
|
|
</Project>
|
|
```
|
|
|
|
#### Step 2: Create Installer Definition (Product.wxs)
|
|
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
|
<Package
|
|
Name="Jellyfin Server (PostgreSQL Edition)"
|
|
Manufacturer="Your Name"
|
|
Version="11.0.0.0"
|
|
UpgradeCode="PUT-YOUR-GUID-HERE">
|
|
|
|
<MajorUpgrade
|
|
DowngradeErrorMessage="A newer version is already installed." />
|
|
|
|
<Media Id="1" Cabinet="jellyfin.cab" EmbedCab="yes" />
|
|
|
|
<!-- Installation Directory -->
|
|
<StandardDirectory Id="ProgramFiles64Folder">
|
|
<Directory Id="INSTALLFOLDER" Name="Jellyfin">
|
|
<Directory Id="BinFolder" Name="bin" />
|
|
<Directory Id="DataFolder" Name="data" />
|
|
</Directory>
|
|
</StandardDirectory>
|
|
|
|
<!-- Program Data Directory -->
|
|
<StandardDirectory Id="CommonAppDataFolder">
|
|
<Directory Id="ProgramDataFolder" Name="jellyfin" />
|
|
</StandardDirectory>
|
|
|
|
<!-- Components -->
|
|
<ComponentGroup Id="ProductComponents" Directory="BinFolder">
|
|
<!-- Harvest all files from lib\Release\net11.0 -->
|
|
<Component Id="JellyfinExe">
|
|
<File Source="$(var.SolutionDir)lib\Release\net11.0\jellyfin.dll" />
|
|
<File Source="$(var.SolutionDir)lib\Release\net11.0\jellyfin.exe" />
|
|
<!-- Add more files... -->
|
|
</Component>
|
|
</ComponentGroup>
|
|
|
|
<!-- Service Component -->
|
|
<Component Id="JellyfinService" Directory="BinFolder">
|
|
<ServiceInstall
|
|
Id="JellyfinServiceInstaller"
|
|
Type="ownProcess"
|
|
Name="JellyfinPostgreSQL"
|
|
DisplayName="Jellyfin Server (PostgreSQL)"
|
|
Description="Jellyfin media server with PostgreSQL support"
|
|
Start="auto"
|
|
Account="LocalSystem"
|
|
ErrorControl="normal"
|
|
Arguments='--service'
|
|
/>
|
|
<ServiceControl
|
|
Id="JellyfinServiceControl"
|
|
Start="install"
|
|
Stop="both"
|
|
Remove="uninstall"
|
|
Name="JellyfinPostgreSQL"
|
|
Wait="yes" />
|
|
</Component>
|
|
|
|
<!-- Start Menu Shortcuts -->
|
|
<StandardDirectory Id="ProgramMenuFolder">
|
|
<Directory Id="ApplicationProgramsFolder" Name="Jellyfin">
|
|
<Component Id="ApplicationShortcuts">
|
|
<Shortcut
|
|
Id="JellyfinShortcut"
|
|
Name="Jellyfin Server (PostgreSQL)"
|
|
Description="Start Jellyfin media server"
|
|
Target="[BinFolder]jellyfin.exe"
|
|
WorkingDirectory="BinFolder" />
|
|
<RemoveFolder Id="CleanUpShortCut" On="uninstall" />
|
|
</Component>
|
|
</Directory>
|
|
</StandardDirectory>
|
|
|
|
<!-- Features -->
|
|
<Feature Id="ProductFeature" Title="Jellyfin Server" Level="1">
|
|
<ComponentGroupRef Id="ProductComponents" />
|
|
<ComponentRef Id="JellyfinService" />
|
|
<ComponentRef Id="ApplicationShortcuts" />
|
|
</Feature>
|
|
|
|
<!-- UI -->
|
|
<WixVariable Id="WixUILicenseRtf" Value="License.rtf" />
|
|
<UIRef Id="WixUI_InstallDir" />
|
|
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
|
</Package>
|
|
</Wix>
|
|
```
|
|
|
|
#### Step 3: Build the Installer
|
|
|
|
```powershell
|
|
# Add WiX project to solution
|
|
dotnet new wix -n Jellyfin.Installer -o Jellyfin.Installer
|
|
dotnet sln add Jellyfin.Installer/Jellyfin.Installer.csproj
|
|
|
|
# Build installer
|
|
dotnet build Jellyfin.Installer --configuration Release
|
|
|
|
# Output: Jellyfin.Installer\bin\Release\JellyfinSetup-PostgreSQL-11.0.0.msi
|
|
```
|
|
|
|
---
|
|
|
|
## ⚡ Quick Option: Inno Setup (Easier but Less Features)
|
|
|
|
### Why Inno Setup?
|
|
- ✅ Very easy to use
|
|
- ✅ Script-based (no XML)
|
|
- ✅ Small installer size
|
|
- ✅ Free
|
|
- ❌ Less Windows Installer integration than WiX
|
|
|
|
### Prerequisites
|
|
```powershell
|
|
# Download from: https://jrsoftware.org/isinfo.php
|
|
winget install --id JRSoftware.InnoSetup
|
|
```
|
|
|
|
### Implementation: Create Setup Script (jellyfin-setup.iss)
|
|
|
|
```pascal
|
|
; Jellyfin PostgreSQL Edition Installer
|
|
[Setup]
|
|
AppName=Jellyfin Server (PostgreSQL Edition)
|
|
AppVersion=11.0.0
|
|
DefaultDirName={autopf}\Jellyfin
|
|
DefaultGroupName=Jellyfin
|
|
OutputDir=installer-output
|
|
OutputBaseFilename=JellyfinSetup-PostgreSQL-11.0.0
|
|
Compression=lzma2
|
|
SolidCompression=yes
|
|
ArchitecturesAllowed=x64
|
|
ArchitecturesInstallIn64BitMode=x64
|
|
PrivilegesRequired=admin
|
|
SetupIconFile=jellyfin.ico
|
|
|
|
[Languages]
|
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
|
|
|
[Tasks]
|
|
Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"
|
|
Name: "service"; Description: "Install as Windows Service"; GroupDescription: "Service Options:"; Flags: unchecked
|
|
|
|
[Files]
|
|
; Copy all files from lib\Release\net11.0
|
|
Source: "lib\Release\net11.0\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
|
; Copy startup configuration
|
|
Source: "Jellyfin.Server\Resources\Configuration\startup.windows.json"; DestDir: "{app}"; DestName: "startup.json"; Flags: onlyifdoesntexist
|
|
|
|
[Dirs]
|
|
; Create program data directories
|
|
Name: "{commonappdata}\jellyfin"; Permissions: users-modify
|
|
Name: "{commonappdata}\jellyfin\data"; Permissions: users-modify
|
|
Name: "{commonappdata}\jellyfin\log"; Permissions: users-modify
|
|
Name: "{commonappdata}\jellyfin\cache"; Permissions: users-modify
|
|
|
|
[Icons]
|
|
Name: "{group}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"
|
|
Name: "{group}\Jellyfin Web Interface"; Filename: "http://localhost:8096"
|
|
Name: "{commondesktop}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"; Tasks: desktopicon
|
|
|
|
[Run]
|
|
; Open web interface after install
|
|
Filename: "http://localhost:8096"; Description: "Open Jellyfin Web Interface"; Flags: postinstall shellexec skipifsilent
|
|
|
|
; Install as service (optional)
|
|
Filename: "sc.exe"; Parameters: "create JellyfinPostgreSQL binPath= ""{app}\jellyfin.exe --service"" start= auto"; Tasks: service; Flags: runhidden
|
|
Filename: "sc.exe"; Parameters: "description JellyfinPostgreSQL ""Jellyfin media server with PostgreSQL support"""; Tasks: service; Flags: runhidden
|
|
Filename: "sc.exe"; Parameters: "start JellyfinPostgreSQL"; Tasks: service; Flags: runhidden waituntilterminated
|
|
|
|
[UninstallRun]
|
|
; Stop and remove service if it exists
|
|
Filename: "sc.exe"; Parameters: "stop JellyfinPostgreSQL"; Flags: runhidden
|
|
Filename: "sc.exe"; Parameters: "delete JellyfinPostgreSQL"; Flags: runhidden
|
|
|
|
[Code]
|
|
// Custom code for install dialogs
|
|
function InitializeSetup(): Boolean;
|
|
begin
|
|
Result := True;
|
|
// Check for .NET 11 runtime
|
|
if not RegKeyExists(HKLM, 'SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost') then
|
|
begin
|
|
MsgBox('.NET 11 Runtime is required. Please install it first.', mbError, MB_OK);
|
|
Result := False;
|
|
end;
|
|
end;
|
|
```
|
|
|
|
### Build Inno Setup Installer
|
|
|
|
```powershell
|
|
# Compile the script
|
|
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" jellyfin-setup.iss
|
|
|
|
# Output: installer-output\JellyfinSetup-PostgreSQL-11.0.0.exe
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Modern Option: MSIX (Windows 10/11 Only)
|
|
|
|
### Why MSIX?
|
|
- ✅ Modern Windows app packaging
|
|
- ✅ Automatic updates via Microsoft Store
|
|
- ✅ Clean install/uninstall
|
|
- ✅ Sandboxed security
|
|
- ❌ Windows 10 1809+ only
|
|
- ❌ Requires code signing certificate
|
|
|
|
### Implementation: Add MSIX Project
|
|
|
|
```xml
|
|
<!-- Jellyfin.Package.csproj -->
|
|
<Project Sdk="Microsoft.NET.Sdk">
|
|
<PropertyGroup>
|
|
<OutputType>WinExe</OutputType>
|
|
<TargetFramework>net11.0-windows10.0.19041.0</TargetFramework>
|
|
<GenerateAppxPackageOnBuild>true</GenerateAppxPackageOnBuild>
|
|
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
|
|
</PropertyGroup>
|
|
|
|
<ItemGroup>
|
|
<ProjectReference Include="..\Jellyfin.Server\Jellyfin.Server.csproj" />
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<Content Include="Images\StoreLogo.png" />
|
|
<Content Include="Images\Square44x44Logo.png" />
|
|
<Content Include="Images\Square150x150Logo.png" />
|
|
<Content Include="Images\Wide310x150Logo.png" />
|
|
</ItemGroup>
|
|
</Project>
|
|
```
|
|
|
|
---
|
|
|
|
## 📦 Simple Option: Self-Contained Publish + ZIP
|
|
|
|
### Why Zip?
|
|
- ✅ Simplest approach
|
|
- ✅ No installer needed
|
|
- ✅ Portable
|
|
- ❌ No service install
|
|
- ❌ No shortcuts
|
|
- ❌ No uninstaller
|
|
|
|
### Implementation
|
|
|
|
```powershell
|
|
# Publish self-contained
|
|
dotnet publish Jellyfin.Server `
|
|
--configuration Release `
|
|
--runtime win-x64 `
|
|
--self-contained true `
|
|
--output "publish\jellyfin-pgsql-win-x64" `
|
|
/p:PublishSingleFile=false `
|
|
/p:IncludeNativeLibrariesForSelfExtract=true
|
|
|
|
# Create ZIP
|
|
Compress-Archive `
|
|
-Path "publish\jellyfin-pgsql-win-x64\*" `
|
|
-DestinationPath "jellyfin-pgsql-11.0.0-win-x64.zip"
|
|
```
|
|
|
|
### Include README in ZIP
|
|
|
|
```markdown
|
|
# Jellyfin Server (PostgreSQL Edition)
|
|
|
|
## Installation
|
|
|
|
1. Extract this ZIP to C:\Jellyfin (or any location)
|
|
2. Run `jellyfin.exe`
|
|
3. Open http://localhost:8096 in your browser
|
|
4. Follow setup wizard
|
|
|
|
## Install as Windows Service
|
|
|
|
Run as Administrator:
|
|
```cmd
|
|
sc create JellyfinPostgreSQL binPath= "C:\Jellyfin\jellyfin.exe --service" start= auto
|
|
sc description JellyfinPostgreSQL "Jellyfin media server with PostgreSQL"
|
|
sc start JellyfinPostgreSQL
|
|
```
|
|
|
|
## Uninstall Service
|
|
|
|
```cmd
|
|
sc stop JellyfinPostgreSQL
|
|
sc delete JellyfinPostgreSQL
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Edit `startup.json` to customize paths.
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Recommended Approach for You
|
|
|
|
### For Production Distribution: **WiX Toolset**
|
|
|
|
**Why:**
|
|
- Professional MSI installer
|
|
- Windows Service support
|
|
- Proper upgrade handling
|
|
- Includes PostgreSQL setup guidance
|
|
|
|
**Next Steps:**
|
|
|
|
1. **Install WiX**
|
|
```powershell
|
|
winget install --id WiX.Toolset
|
|
```
|
|
|
|
2. **Create Installer Project**
|
|
```powershell
|
|
mkdir Jellyfin.Installer
|
|
cd Jellyfin.Installer
|
|
# Create Product.wxs file (see template above)
|
|
```
|
|
|
|
3. **Add to Solution**
|
|
```powershell
|
|
dotnet sln add Jellyfin.Installer/Jellyfin.Installer.csproj
|
|
```
|
|
|
|
4. **Build**
|
|
```powershell
|
|
dotnet build Jellyfin.Installer --configuration Release
|
|
```
|
|
|
|
### For Quick Testing: **Inno Setup**
|
|
|
|
**Why:**
|
|
- Fast to create
|
|
- Easy to customize
|
|
- Good for internal testing
|
|
|
|
**Next Steps:**
|
|
|
|
1. **Install Inno Setup**
|
|
```powershell
|
|
winget install JRSoftware.InnoSetup
|
|
```
|
|
|
|
2. **Create Script**
|
|
- Use template above
|
|
- Save as `jellyfin-setup.iss`
|
|
|
|
3. **Compile**
|
|
```powershell
|
|
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" jellyfin-setup.iss
|
|
```
|
|
|
|
---
|
|
|
|
## Additional Installer Features to Consider
|
|
|
|
### PostgreSQL Database Setup
|
|
|
|
Add to installer:
|
|
|
|
```xml
|
|
<!-- WiX: Check for PostgreSQL -->
|
|
<Property Id="POSTGRESQLINSTALLED">
|
|
<RegistrySearch Id="PostgreSQLSearch"
|
|
Root="HKLM"
|
|
Key="SOFTWARE\PostgreSQL\Installations\postgresql-x64-16"
|
|
Name="Version"
|
|
Type="raw" />
|
|
</Property>
|
|
|
|
<Condition Message="PostgreSQL 12+ is required. Please install PostgreSQL first.">
|
|
Installed OR POSTGRESQLINSTALLED
|
|
</Condition>
|
|
```
|
|
|
|
### Firewall Rules
|
|
|
|
```xml
|
|
<!-- Add Windows Firewall exception -->
|
|
<Component Id="FirewallException">
|
|
<fire:FirewallException Id="JellyfinFirewall"
|
|
Name="Jellyfin Server"
|
|
Port="8096"
|
|
Protocol="tcp"
|
|
Scope="any" />
|
|
</Component>
|
|
```
|
|
|
|
### Database Migration Wizard
|
|
|
|
Include a post-install wizard for:
|
|
- PostgreSQL connection setup
|
|
- Database migration from SQLite
|
|
- Initial configuration
|
|
|
|
---
|
|
|
|
## Testing Your Installer
|
|
|
|
### Test Checklist
|
|
|
|
- [ ] Fresh Windows install
|
|
- [ ] Upgrade from previous version
|
|
- [ ] Silent install: `msiexec /i JellyfinSetup.msi /quiet`
|
|
- [ ] Custom install directory
|
|
- [ ] Service starts automatically
|
|
- [ ] Firewall rules created
|
|
- [ ] Shortcuts work
|
|
- [ ] Uninstall removes everything
|
|
- [ ] Data preserved on upgrade
|
|
|
|
### Test Commands
|
|
|
|
```powershell
|
|
# Install silently
|
|
msiexec /i JellyfinSetup-PostgreSQL-11.0.0.msi /quiet /l*v install.log
|
|
|
|
# Uninstall silently
|
|
msiexec /x JellyfinSetup-PostgreSQL-11.0.0.msi /quiet
|
|
|
|
# Upgrade
|
|
msiexec /i JellyfinSetup-PostgreSQL-11.0.1.msi /quiet
|
|
```
|
|
|
|
---
|
|
|
|
## Distribution
|
|
|
|
### Code Signing (Recommended)
|
|
|
|
Get a code signing certificate:
|
|
- DigiCert
|
|
- Sectigo
|
|
- SignPath (free for open source)
|
|
|
|
Sign your installer:
|
|
```powershell
|
|
signtool sign /f certificate.pfx /p password /t http://timestamp.digicert.com JellyfinSetup.msi
|
|
```
|
|
|
|
### Release Strategy
|
|
|
|
1. **GitHub Releases**
|
|
```yaml
|
|
# .github/workflows/release.yml
|
|
- name: Build Installer
|
|
run: dotnet build Jellyfin.Installer --configuration Release
|
|
|
|
- name: Upload Release Asset
|
|
uses: actions/upload-release-asset@v1
|
|
with:
|
|
asset_path: Jellyfin.Installer/bin/Release/JellyfinSetup.msi
|
|
asset_name: jellyfin-pgsql-windows-${{ github.ref }}.msi
|
|
```
|
|
|
|
2. **Versioning**
|
|
- Use semantic versioning: 11.0.0
|
|
- Include in filename: JellyfinSetup-PostgreSQL-11.0.0.msi
|
|
- Update UpgradeCode for major versions only
|
|
|
|
---
|
|
|
|
## Quick Start Script
|
|
|
|
I can create a PowerShell script to help you set up the installer project:
|
|
|
|
```powershell
|
|
# setup-installer.ps1
|
|
param(
|
|
[Parameter(Mandatory=$false)]
|
|
[ValidateSet("WiX", "InnoSetup", "Both")]
|
|
[string]$Type = "InnoSetup"
|
|
)
|
|
|
|
Write-Host "Setting up Jellyfin installer project..." -ForegroundColor Cyan
|
|
|
|
# Your current setup
|
|
$solutionRoot = "E:\Projects\pgsql-jellyfin"
|
|
$libFolder = "$solutionRoot\lib\Release\net11.0"
|
|
|
|
if ($Type -eq "InnoSetup" -or $Type -eq "Both") {
|
|
# Create Inno Setup script
|
|
# ... (see template above)
|
|
}
|
|
|
|
if ($Type -eq "WiX" -or $Type -eq "Both") {
|
|
# Create WiX project
|
|
# ... (see template above)
|
|
}
|
|
|
|
Write-Host "Installer setup complete!" -ForegroundColor Green
|
|
```
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
**Recommended for You: Inno Setup** (Quick start)
|
|
- Easiest to implement immediately
|
|
- Creates professional .exe installer
|
|
- Includes service install option
|
|
|
|
**Future: Migrate to WiX** (Production)
|
|
- Industry standard
|
|
- Better upgrade handling
|
|
- Full MSI features
|
|
|
|
**Want me to create the installer project for you?** Just let me know which approach you prefer!
|
|
|
|
---
|
|
|
|
**Files Needed:**
|
|
- [ ] jellyfin.ico (icon file)
|
|
- [ ] License.rtf (license text)
|
|
- [ ] README.md (user instructions)
|
|
- [ ] PostgreSQL setup guide
|
|
|
|
**Estimated Time:**
|
|
- Inno Setup: 30 minutes
|
|
- WiX Setup: 2-4 hours
|
|
- MSIX: 1-2 hours
|
|
|
|
Let me know which installer type you'd like me to help you implement!
|