@@ -68,12 +68,38 @@ static void ApplyJsonDefaults(System.Text.Json.JsonSerializerOptions opts)
6868// usually want to control migrations manually) stays unchanged. Coolify deploys set this to
6969// `true` in prod env so a fresh Postgres container gets the full schema on its first boot.
7070// Idempotent on every later boot: EF checks __EFMigrationsHistory and no-ops if up-to-date.
71- // On migration failure the container exits non-zero → Coolify keeps the previous image running.
71+ //
72+ // Retry loop: on first deploy Coolify spins up Postgres and the API container nearly
73+ // simultaneously, so Npgsql's first DNS resolve can fail with `EAI_AGAIN` (Docker's embedded DNS
74+ // hasn't propagated the alias yet) or `Connection refused` (Postgres still initializing). We back
75+ // off up to a minute total — long enough for Postgres init, short enough that a genuinely broken
76+ // connection string still surfaces as a deploy failure for Coolify to roll back.
7277if ( builder . Configuration . GetValue < bool > ( "MIGRATE_ON_STARTUP" ) )
7378{
7479 using IServiceScope migrationScope = app . Services . CreateScope ( ) ;
7580 var db = migrationScope . ServiceProvider . GetRequiredService < ApplicationDbContext > ( ) ;
76- await db . Database . MigrateAsync ( ) ;
81+ var migrationLogger = migrationScope . ServiceProvider
82+ . GetRequiredService < ILoggerFactory > ( )
83+ . CreateLogger ( "Coiny.Migration" ) ;
84+
85+ const int maxAttempts = 12 ;
86+ TimeSpan delay = TimeSpan . FromSeconds ( 5 ) ;
87+ for ( int attempt = 1 ; ; attempt ++ )
88+ {
89+ try
90+ {
91+ await db . Database . MigrateAsync ( ) ;
92+ migrationLogger . LogInformation ( "EF migrations applied on attempt {Attempt}" , attempt ) ;
93+ break ;
94+ }
95+ catch ( Exception ex ) when ( attempt < maxAttempts )
96+ {
97+ migrationLogger . LogWarning ( ex ,
98+ "EF migration attempt {Attempt} failed ({Error}); retrying in {Delay}s" ,
99+ attempt , ex . Message , delay . TotalSeconds ) ;
100+ await Task . Delay ( delay ) ;
101+ }
102+ }
77103}
78104
79105app . UseExceptionHandler ( ) ;
0 commit comments