@@ -3387,9 +3387,22 @@ def log_response_info(response):
33873387 for rule in app .url_map .iter_rules (): logger .info (f" { rule .methods } { rule .rule } -> { rule .endpoint } " )
33883388 db .create_all (); migrate_sqlite_to_pg (app )
33893389
3390- # Run any pending database migrations
3390+ # Detect fresh install BEFORE running migrations
3391+ # Fresh install = no users AND no schema_migrations table
3392+ from sqlalchemy import inspect as sa_inspect
3393+ inspector = sa_inspect (db .engine )
3394+ is_fresh_install = 'schema_migrations' not in inspector .get_table_names () and User .query .count () == 0
3395+
3396+ # Run any pending database migrations (skip on fresh install - schema is already current)
33913397 logger .info ("🔄 Checking for pending database migrations..." )
3392- run_pending_migrations (db )
3398+ if is_fresh_install :
3399+ from db_migrations import ensure_migrations_table , record_migration , MIGRATIONS
3400+ ensure_migrations_table (db )
3401+ for version , description , _ in MIGRATIONS :
3402+ record_migration (db , version , description )
3403+ logger .info (f"✨ Fresh install - marked { len (MIGRATIONS )} migrations as applied (schema already current)" )
3404+ else :
3405+ run_pending_migrations (db )
33933406
33943407 # First-run detection: only create defaults if NO users exist
33953408 user_count = User .query .count ()
@@ -3405,14 +3418,15 @@ def log_response_info(response):
34053418 db .session .flush () # Get IDs before linking
34063419 admin .accessible_databases .append (p_db )
34073420 db .session .commit ()
3408- # Print password to console only (not to log file) for initial setup
3409- print ("\n " + "=" * 60 )
3410- print ("🔐 INITIAL ADMIN CREDENTIALS (save these now!)" )
3411- print (f" Username: admin" )
3412- print (f" Password: { initial_password } " )
3413- print (" You will be required to change this password on first login." )
3414- print ("=" * 60 + "\n " )
3415- logger .info ("✅ Default admin and database created (credentials printed to console)" )
3421+ # Print credentials to stderr so Docker logs capture them
3422+ import sys
3423+ print ("\n " + "=" * 60 , file = sys .stderr )
3424+ print ("🔐 INITIAL ADMIN CREDENTIALS (save these now!)" , file = sys .stderr )
3425+ print (f" Username: admin" , file = sys .stderr )
3426+ print (f" Password: { initial_password } " , file = sys .stderr )
3427+ print (" You will be required to change this password on first login." , file = sys .stderr )
3428+ print ("=" * 60 + "\n " , file = sys .stderr )
3429+ logger .info ("✅ Default admin and database created" )
34163430 else :
34173431 logger .info (f"📦 Existing installation detected ({ user_count } users) - skipping default creation" )
34183432 except Exception as e : logger .error (f"❌ Startup Error: { e } " )
0 commit comments