retry the quick connect startup probe, and exit non-zero when a start fails
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
2026-09-26 22:14:14 +10:00
parent 624d528d28
commit 6c7f76fd26
8 changed files with 312 additions and 64 deletions
+14 -2
View File
@@ -54,6 +54,13 @@ namespace Jellyfin.Server
/// </summary>
public const string LoggingConfigFileSystem = "logging.json";
/// <summary>
/// How long a failed start keeps the setup server answering before the process exits, so an
/// install without a supervisor shows the failure instead of spinning. Skipped under an
/// orchestrator, where restarting is its job and holding only stretches the crash loop.
/// </summary>
private static readonly TimeSpan _setupServerHoldAfterFailedStart = TimeSpan.FromMinutes(10);
private static readonly SerilogLoggerFactory _loggerFactory = new SerilogLoggerFactory();
private static SetupServer? _setupServer;
private static CoreAppHost? _appHost;
@@ -255,13 +262,14 @@ namespace Jellyfin.Server
catch (Exception ex)
{
_restartOnShutdown = false;
Environment.ExitCode = 1;
_logger.LogCritical(ex, "Error while starting server");
if (_setupServer!.IsAlive && !configurationCompleted)
{
_setupServer!.SoftStop();
if (options.StartupMode is null or Configuration.StartupMode.MediaServer)
if (options.StartupMode is null or Configuration.StartupMode.MediaServer && !IsRunningInContainer())
{
await Task.Delay(TimeSpan.FromMinutes(10)).ConfigureAwait(false);
await Task.Delay(_setupServerHoldAfterFailedStart).ConfigureAwait(false);
}
await _setupServer!.StopAsync().ConfigureAwait(false);
@@ -285,6 +293,10 @@ namespace Jellyfin.Server
}
}
// Set by every official .NET base image, including the one this server ships in.
private static bool IsRunningInContainer()
=> string.Equals(Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"), "true", StringComparison.OrdinalIgnoreCase);
/// <summary>
/// [Internal]Runs the startup Migrations.
/// </summary>