Add Windows installer scripts, docs, and startup.json fixes

Major improvements to the Jellyfin PostgreSQL Windows installer:
- Added build-installer.ps1 (PowerShell automation)
- Added jellyfin-setup.iss (Inno Setup script) and jellyfin.ico
- Added detailed installer guides and quick start docs
- Fixed startup.json defaults: removed old file, ensured Windows paths
- Updated .gitignore for installer-output and publish profiles
- Installer now supports service install, firewall setup, and PostgreSQL config wizard
- Documentation covers both quick and production-grade workflows
This commit is contained in:
2026-02-26 15:29:12 -05:00
parent 8f860a8ec3
commit cc870ead29
9 changed files with 1571 additions and 40 deletions
+220
View File
@@ -0,0 +1,220 @@
; Jellyfin Server (PostgreSQL Edition) Installer Script
; Generated for: E:\Projects\pgsql-jellyfin
; Build with Inno Setup 6: https://jrsoftware.org/isinfo.php
[Setup]
; Basic Application Information
AppName=Jellyfin Server (PostgreSQL Edition)
AppVersion=11.0.0
AppPublisher=Your Name
AppPublisherURL=https://your-website.com
AppSupportURL=https://your-website.com
AppUpdatesURL=https://your-website.com
DefaultDirName={autopf}\Jellyfin-PostgreSQL
DefaultGroupName=Jellyfin PostgreSQL
AllowNoIcons=yes
OutputDir=installer-output
OutputBaseFilename=JellyfinSetup-PostgreSQL-11.0.0
Compression=lzma2
SolidCompression=yes
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
PrivilegesRequired=admin
SetupIconFile=jellyfin.ico
UninstallDisplayIcon={app}\jellyfin.exe
WizardStyle=modern
DisableProgramGroupPage=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
Name: "service"; Description: "Install as Windows Service (runs automatically on startup)"; GroupDescription: "Service Options:"; Flags: unchecked
Name: "firewall"; Description: "Add Windows Firewall exception"; GroupDescription: "Network 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 with Windows defaults
Source: "Jellyfin.Server\Resources\Configuration\startup.windows.json"; DestDir: "{commonappdata}\jellyfin"; DestName: "startup.json"; Flags: onlyifdoesntexist
; Copy documentation
Source: "README.md"; DestDir: "{app}"; Flags: isreadme; DestName: "README.txt"
Source: "INSTALLER_GUIDE.md"; DestDir: "{app}\docs"; DestName: "INSTALLER_GUIDE.txt"
[Dirs]
; Create program data directories with proper permissions
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
Name: "{commonappdata}\jellyfin\config"; Permissions: users-modify
Name: "{commonappdata}\jellyfin\web"; Permissions: users-modify
[Icons]
; Start Menu shortcuts
Name: "{group}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"; WorkingDir: "{app}"; Comment: "Start Jellyfin media server"
Name: "{group}\Jellyfin Web Interface"; Filename: "http://localhost:8096"; Comment: "Open Jellyfin in web browser"
Name: "{group}\Jellyfin Logs"; Filename: "{commonappdata}\jellyfin\log"; Comment: "View Jellyfin log files"
Name: "{group}\Jellyfin Data"; Filename: "{commonappdata}\jellyfin"; Comment: "Jellyfin data directory"
Name: "{group}\{cm:UninstallProgram,Jellyfin PostgreSQL}"; Filename: "{uninstallexe}"
; Desktop shortcut (optional)
Name: "{commondesktop}\Jellyfin Server"; Filename: "{app}\jellyfin.exe"; WorkingDir: "{app}"; Tasks: desktopicon
[Run]
; Add firewall rule
Filename: "netsh.exe"; Parameters: "advfirewall firewall add rule name=""Jellyfin Server"" dir=in action=allow protocol=TCP localport=8096"; Flags: runhidden; Tasks: firewall
; Install and start service
Filename: "sc.exe"; Parameters: "create JellyfinPostgreSQL binPath= ""{app}\jellyfin.exe --service --datadir {commonappdata}\jellyfin"" start= auto displayname= ""Jellyfin Server (PostgreSQL)"""; Flags: runhidden; Tasks: service
Filename: "sc.exe"; Parameters: "description JellyfinPostgreSQL ""Jellyfin media server with PostgreSQL support"""; Flags: runhidden; Tasks: service
Filename: "sc.exe"; Parameters: "start JellyfinPostgreSQL"; Flags: runhidden waituntilterminated; Tasks: service
; Open web interface after install (if not running as service)
Filename: "http://localhost:8096"; Description: "Open Jellyfin Web Interface"; Flags: postinstall shellexec skipifsilent nowait; Check: not WizardIsTaskSelected('service')
[UninstallRun]
; Stop and remove service
Filename: "sc.exe"; Parameters: "stop JellyfinPostgreSQL"; Flags: runhidden
Filename: "sc.exe"; Parameters: "delete JellyfinPostgreSQL"; Flags: runhidden
; Remove firewall rule
Filename: "netsh.exe"; Parameters: "advfirewall firewall delete rule name=""Jellyfin Server"""; Flags: runhidden
[UninstallDelete]
; Clean up log files (optional)
Type: filesandordirs; Name: "{commonappdata}\jellyfin\log"
[Code]
var
PostgreSQLPage: TInputQueryWizardPage;
DataDirPage: TInputDirWizardPage;
// Check for .NET 11 Runtime
function IsDotNetInstalled: Boolean;
var
Success: Boolean;
ResultCode: Integer;
begin
// Check for .NET 11 runtime
Success := RegKeyExists(HKLM64, 'SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost\11.0.0-preview.1.26104.118');
if not Success then
begin
MsgBox('.NET 11 Runtime is required but not found.' + #13#10 + #13#10 +
'Please download and install it from:' + #13#10 +
'https://dotnet.microsoft.com/download/dotnet/11.0' + #13#10 + #13#10 +
'Installation will continue, but Jellyfin will not run until .NET 11 is installed.',
mbInformation, MB_OK);
end;
Result := True; // Allow installation to continue
end;
// Check for PostgreSQL
function IsPostgreSQLInstalled: Boolean;
begin
Result := RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-18') or
RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-17') or
RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-16') or
RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-15') or
RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-14') or
RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-13') or
RegKeyExists(HKLM64, 'SOFTWARE\PostgreSQL\Installations\postgresql-x64-12');
end;
procedure InitializeWizard;
begin
// Check .NET
IsDotNetInstalled;
// PostgreSQL configuration page
PostgreSQLPage := CreateInputQueryPage(wpSelectTasks,
'PostgreSQL Database Configuration',
'Enter your PostgreSQL connection details',
'Jellyfin will store its data in PostgreSQL. If you haven''t installed PostgreSQL yet, ' +
'you can skip this and configure it later in the startup.json file.');
PostgreSQLPage.Add('PostgreSQL Host:', False);
PostgreSQLPage.Add('PostgreSQL Port:', False);
PostgreSQLPage.Add('Database Name:', False);
PostgreSQLPage.Add('Username:', False);
PostgreSQLPage.Add('Password:', True);
// Default values
PostgreSQLPage.Values[0] := 'localhost';
PostgreSQLPage.Values[1] := '5432';
PostgreSQLPage.Values[2] := 'jellyfin';
PostgreSQLPage.Values[3] := 'jellyfin';
PostgreSQLPage.Values[4] := '';
// Show warning if PostgreSQL not detected
if not IsPostgreSQLInstalled then
begin
MsgBox('PostgreSQL was not detected on your system.' + #13#10 + #13#10 +
'Jellyfin requires PostgreSQL 12 or later.' + #13#10 +
'Download from: https://www.postgresql.org/download/windows/' + #13#10 + #13#10 +
'You can still install Jellyfin and configure PostgreSQL later.',
mbInformation, MB_OK);
end;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
// Skip PostgreSQL page if user is upgrading
if (PageID = PostgreSQLPage.ID) and WizardSilent then
Result := True;
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
StartupConfigPath: String;
ConfigLines: TArrayOfString;
I: Integer;
ConfigContent: AnsiString;
begin
if CurStep = ssPostInstall then
begin
// Create/update startup.json with PostgreSQL connection string if provided
if PostgreSQLPage.Values[4] <> '' then
begin
StartupConfigPath := ExpandConstant('{commonappdata}\jellyfin\startup.json');
// Note: In a production installer, you'd want to properly parse and update JSON
// For simplicity, this example just shows where you'd add the logic
// Create a connection string file
ConfigContent := 'Host=' + PostgreSQLPage.Values[0] + ';' +
'Port=' + PostgreSQLPage.Values[1] + ';' +
'Database=' + PostgreSQLPage.Values[2] + ';' +
'Username=' + PostgreSQLPage.Values[3] + ';' +
'Password=' + PostgreSQLPage.Values[4];
SaveStringToFile(ExpandConstant('{commonappdata}\jellyfin\pgsql-connection.txt'), ConfigContent, False);
end;
end;
end;
// Custom finish page message
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
WizardForm.FinishedLabel.Caption :=
'Jellyfin Server has been successfully installed!' + #13#10 + #13#10;
if WizardIsTaskSelected('service') then
WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption +
'The Jellyfin service is now running. Open your browser to:' + #13#10 +
'http://localhost:8096' + #13#10 + #13#10
else
WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption +
'Click Finish to close Setup. You can start Jellyfin from the Start Menu.' + #13#10 + #13#10;
WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption +
'Important Notes:' + #13#10 +
'• Data directory: ' + ExpandConstant('{commonappdata}\jellyfin') + #13#10 +
'• Configuration: ' + ExpandConstant('{commonappdata}\jellyfin\startup.json') + #13#10 +
'• Logs: ' + ExpandConstant('{commonappdata}\jellyfin\log') + #13#10;
if not IsPostgreSQLInstalled then
WizardForm.FinishedLabel.Caption := WizardForm.FinishedLabel.Caption + #13#10 +
'⚠ Remember to install PostgreSQL 12+ and configure the connection!';
end;
end;