diff --git a/CHANGELOG.md b/CHANGELOG.md index 71dcb71..fd72f90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.3.8] - 2026-04-26 + +### Fixed + +- **Startup / database:** `InitializationHostedService` now runs FluentMigrator (`EnsureCertsEngineMigratedAsync`) before acquiring the bootstrap PostgreSQL lease, so `app_runtime_leases` exists on an empty database (same ordering idea as Vault: migrate first, then coordination). +- **Startup:** While waiting for the bootstrap lease, migrations are not re-run on every poll interval (`migrationsApplied` guard). + +### Changed + +- **Container image:** `MaksIT.CertsUI` Dockerfile installs `libgssapi-krb5-2` so Npgsql can load GSS/Kerberos support without missing-library warnings on slim `aspnet` images. + ## [3.3.7] - 2026-04-25 ### Added diff --git a/assets/badges/coverage-branches.svg b/assets/badges/coverage-branches.svg index de27bdb..8304471 100644 --- a/assets/badges/coverage-branches.svg +++ b/assets/badges/coverage-branches.svg @@ -1,5 +1,5 @@ - - Branch Coverage: 7.9% + + Branch Coverage: 7.8% @@ -15,7 +15,7 @@ Branch Coverage - - 7.9% + + 7.8% diff --git a/src/MaksIT.CertsUI/Dockerfile b/src/MaksIT.CertsUI/Dockerfile index c18cc6d..7bc26c3 100644 --- a/src/MaksIT.CertsUI/Dockerfile +++ b/src/MaksIT.CertsUI/Dockerfile @@ -21,6 +21,11 @@ ARG BUILD_CONFIGURATION=Release RUN dotnet publish "./MaksIT.CertsUI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false FROM base AS final +USER root +RUN apt-get update \ + && apt-get install -y --no-install-recommends libgssapi-krb5-2 \ + && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=publish /app/publish . +USER app ENTRYPOINT ["dotnet", "MaksIT.CertsUI.dll"] \ No newline at end of file diff --git a/src/MaksIT.CertsUI/HostedServices/InitializationHostedService.cs b/src/MaksIT.CertsUI/HostedServices/InitializationHostedService.cs index 51e6f61..fc1e4dc 100644 --- a/src/MaksIT.CertsUI/HostedServices/InitializationHostedService.cs +++ b/src/MaksIT.CertsUI/HostedServices/InitializationHostedService.cs @@ -8,7 +8,8 @@ namespace MaksIT.CertsUI.HostedServices; /// /// Runs startup initialization (migrations + identity bootstrap) before the API starts serving requests. -/// Uses a PostgreSQL lease so only one replica runs migrations at a time. +/// FluentMigrator runs first on every instance (same pattern as Vault); the bootstrap lease then ensures +/// only one replica performs identity bootstrap against shared . /// public sealed class InitializationHostedService( ILogger logger, @@ -22,11 +23,18 @@ public sealed class InitializationHostedService( public async Task StartAsync(CancellationToken cancellationToken) { const int delayMilliseconds = 2000; + var migrationsApplied = false; while (!cancellationToken.IsCancellationRequested) { try { logger.LogInformation("Running startup initialization..."); + // Migrations must run before lease acquisition: app_runtime_leases is created by FluentMigrator. + if (!migrationsApplied) { + await serviceProvider.EnsureCertsEngineMigratedAsync().ConfigureAwait(false); + migrationsApplied = true; + } + var holder = runtimeInstance.InstanceId; var acquired = await runtimeLease.TryAcquireAsync(RuntimeLeaseNames.Bootstrap, holder, BootstrapLeaseTtl, cancellationToken).ConfigureAwait(false); if (!acquired.IsSuccess) @@ -38,8 +46,6 @@ public sealed class InitializationHostedService( } try { - await serviceProvider.EnsureCertsEngineMigratedAsync().ConfigureAwait(false); - await using var scope = serviceProvider.CreateAsyncScope(); var identityDomainService = scope.ServiceProvider.GetRequiredService(); await EnsureIdentityInitializedAsync(appSettings.Value, identityDomainService, cancellationToken).ConfigureAwait(false); diff --git a/src/MaksIT.CertsUI/MaksIT.CertsUI.csproj b/src/MaksIT.CertsUI/MaksIT.CertsUI.csproj index ddb597c..b03c9c6 100644 --- a/src/MaksIT.CertsUI/MaksIT.CertsUI.csproj +++ b/src/MaksIT.CertsUI/MaksIT.CertsUI.csproj @@ -1,7 +1,7 @@ - 3.3.7 + 3.3.8 net10.0 enable enable