Guard deploys against a broken migration
Program.cs: wrap the boot-time MigrateAsync in try/catch (was an unhandled exception into a restart:unless-stopped crash-loop), log critical and exit(1) on failure, and add a --migrate-only flag that applies migrations then exits 0 without starting the web host. deploy.sh: run migrations as a preflight via the new --migrate-only image against the live novelly-data volume, before the running (old-image) stack is touched. A failing migration now aborts the deploy with the old containers still serving traffic, instead of swapping to a crash-looping new container first and finding out from the health-check timeout.
This commit is contained in:
@@ -41,12 +41,30 @@ builder.Services.AddCors(options => options.AddDefaultPolicy(policy => policy
|
||||
.AllowAnyMethod()
|
||||
.AllowCredentials()));
|
||||
|
||||
var migrateOnly = args.Contains("--migrate-only");
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<NovelDbContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
|
||||
try
|
||||
{
|
||||
await db.Database.MigrateAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
app.Logger.LogCritical(ex, "Database migration failed on startup");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
if (migrateOnly)
|
||||
{
|
||||
app.Logger.LogInformation("Migration complete, exiting ({MigrateOnlyFlag})", "--migrate-only");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
await ServiceUser.EnsureSeededAsync(db, builder.Configuration[ServiceApiKeyAuthenticationHandler.ConfigurationKey], app.Logger);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user