Add user-configurable PostgreSQL backup system

Introduced backup/restore via external pg_dump/pg_restore tools, configurable in database.xml. Added DatabaseBackupOptions, PostgresBackupService, and example/config docs. Backup features are enabled only for local databases; remote DBs require manual management. Logging and documentation clarify external tool usage, error handling, and security. Updated provider logic and assembly files accordingly.
This commit is contained in:
2026-02-23 18:31:27 -05:00
parent 43cdbf9b35
commit 88dba54087
16 changed files with 1637 additions and 14 deletions
@@ -0,0 +1,75 @@
// <copyright file="DatabaseBackupOptions.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>
namespace Jellyfin.Database.Implementations.DbConfiguration;
/// <summary>
/// Options to configure database backup behavior.
/// </summary>
public class DatabaseBackupOptions
{
/// <summary>
/// Gets or sets the path to the pg_dump executable.
/// If not specified, will search in system PATH.
/// </summary>
/// <remarks>
/// Examples:
/// - Windows: "C:\\Program Files\\PostgreSQL\\16\\bin\\pg_dump.exe"
/// - Linux: "/usr/bin/pg_dump"
/// - Use "pg_dump" to search in PATH.
/// </remarks>
public string? PgDumpPath { get; set; }
/// <summary>
/// Gets or sets the path to the pg_restore executable.
/// If not specified, will search in system PATH.
/// </summary>
public string? PgRestorePath { get; set; }
/// <summary>
/// Gets or sets the backup format.
/// </summary>
/// <remarks>
/// Valid values:
/// - "custom" (default): Custom compressed format (pg_restore compatible)
/// - "plain": Plain SQL script
/// - "directory": Directory format
/// - "tar": Tar archive format.
/// </remarks>
public string BackupFormat { get; set; } = "custom";
/// <summary>
/// Gets or sets a value indicating whether to include large objects (blobs) in backup.
/// </summary>
public bool IncludeBlobs { get; set; } = true;
/// <summary>
/// Gets or sets the compression level (0-9, where 9 is maximum compression).
/// Only applies to custom and directory formats.
/// </summary>
public int CompressionLevel { get; set; } = 6;
/// <summary>
/// Gets or sets additional pg_dump arguments.
/// </summary>
/// <remarks>
/// Example: "--verbose --exclude-table-data=public.logs".
/// </remarks>
public string? AdditionalArguments { get; set; }
/// <summary>
/// Gets or sets the timeout in seconds for backup operations.
/// </summary>
public int TimeoutSeconds { get; set; } = 1800; // 30 minutes
/// <summary>
/// Gets or sets a value indicating whether to enable verbose output.
/// </summary>
public bool VerboseOutput { get; set; } = true;
/// <summary>
/// Gets or sets the number of parallel jobs for pg_dump (if format is 'directory').
/// </summary>
public int? ParallelJobs { get; set; }
}
@@ -4,8 +4,6 @@
namespace Jellyfin.Database.Implementations.DbConfiguration;
using System.Collections.Generic;
/// <summary>
/// Options to configure jellyfins managed database.
/// </summary>
@@ -26,4 +24,9 @@ public class DatabaseConfigurationOptions
/// Defaults to "NoLock".
/// </summary>
public DatabaseLockingBehaviorTypes LockingBehavior { get; set; }
/// <summary>
/// Gets or sets the backup configuration options.
/// </summary>
public DatabaseBackupOptions? BackupOptions { get; set; }
}
@@ -0,0 +1,73 @@
<!--
Example database.xml configuration for Jellyfin with PostgreSQL backup options
Place this file in your Jellyfin config directory
-->
<DatabaseConfigurationOptions>
<!-- Database type: "Jellyfin-PostgreSQL" or "Jellyfin-Sqlite" -->
<DatabaseType>Jellyfin-PostgreSQL</DatabaseType>
<!-- Locking behavior: "NoLock", "Pessimistic", or "Optimistic" -->
<LockingBehavior>NoLock</LockingBehavior>
<!-- Custom database provider options (for PostgreSQL) -->
<CustomProviderOptions>
<PluginName>Jellyfin-PostgreSQL</PluginName>
<PluginAssembly>Jellyfin.Database.Providers.Postgres</PluginAssembly>
<ConnectionString>Host=localhost;Port=5432;Database=jellyfin;Username=jellyfin;Password=your_password_here</ConnectionString>
<Options>
<!-- Optional: Override host -->
<CustomDatabaseOption>
<Key>Host</Key>
<Value>localhost</Value>
</CustomDatabaseOption>
<!-- Optional: Override port -->
<CustomDatabaseOption>
<Key>Port</Key>
<Value>5432</Value>
</CustomDatabaseOption>
<!-- Optional: Override database name -->
<CustomDatabaseOption>
<Key>Database</Key>
<Value>jellyfin</Value>
</CustomDatabaseOption>
</Options>
</CustomProviderOptions>
<!-- Database Backup Configuration -->
<!-- NOTE: Backup features using pg_dump/pg_restore are ONLY enabled when -->
<!-- the database host is 'localhost' or '127.0.0.1'. For remote databases, -->
<!-- these settings will be ignored and you must manage backups externally. -->
<BackupOptions>
<!-- Path to pg_dump executable (optional, will search PATH if not specified) -->
<!-- Windows example: C:\Program Files\PostgreSQL\16\bin\pg_dump.exe -->
<!-- Linux example: /usr/bin/pg_dump -->
<PgDumpPath>pg_dump</PgDumpPath>
<!-- Path to pg_restore executable (optional) -->
<PgRestorePath>pg_restore</PgRestorePath>
<!-- Backup format: "custom" (default), "plain", "directory", or "tar" -->
<BackupFormat>custom</BackupFormat>
<!-- Include large objects/blobs in backup -->
<IncludeBlobs>true</IncludeBlobs>
<!-- Compression level (0-9, where 9 is maximum compression) -->
<CompressionLevel>6</CompressionLevel>
<!-- Timeout in seconds for backup operations (default: 1800 = 30 minutes) -->
<TimeoutSeconds>1800</TimeoutSeconds>
<!-- Enable verbose output in logs -->
<VerboseOutput>true</VerboseOutput>
<!-- Number of parallel jobs (only for 'directory' format) -->
<!-- <ParallelJobs>4</ParallelJobs> -->
<!-- Additional pg_dump arguments (optional) -->
<!-- <AdditionalArguments>--exclude-table-data=public.temp_logs</AdditionalArguments> -->
</BackupOptions>
</DatabaseConfigurationOptions>