本番サーバーでEFCoreマイグレーション を実行する時の正解が何かわからない。。。とりあえず今回試した方法を残しておく。
EFCoreのマイグレーションコマンドを実行するにはいくつか手段があるが、手軽なのはdotnet ef
コマンドを使った方法である。
ただし、実行環境にソースコードとDBに接続可能なこと、dotnet efツールのインストールが必要である。
開発環境から本番DBに接続はできない環境のため、ソースコードを本番サーバーにコピーしてコマンド実行する必要があるが、
それは嫌だったのでマイグレーションコマンドと同じ処理を行うコンソールプログラムを生成し、それを本番サーバーで実行することにした。
環境
- OS: Debian9
- DB:Postgresql11
- EFCore:8
本番サーバーでEFCoreマイグレーション 実行用コンソールプログラム作成
DbContextFactory.cs
public class DbContextFactory : IDesignTimeDbContextFactory<ArsenalDbContext> { public DbContext CreateDbContext(string[] args) { string environment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Development"; Console.WriteLine($"DOTNET_ENVIRONMENT:{environment}"); var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("dbsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"dbsettings.{environment}.json", optional: false) .AddEnvironmentVariables() .Build(); string? connectionString = configuration.GetConnectionString("DefaultConnection"); var optionBuilder = new DbContextOptionsBuilder<DbContext>(); optionBuilder.UseNpgsql(connectionString, x => x.MigrationsHistoryTable("__EFMigrationsHistory", DbConst.SchemaName)); return new DbContext(optionBuilder.Options); } }
Program.cs
public class Program { public static int Main(string[] args) { DbContextFactory factory = new DbContextFactory(); using DbContext context = factory.CreateDbContext(args); Console.WriteLine($"Connect Status:{context.Database.CanConnect()}"); context.Database.Migrate(); Console.WriteLine("Migration done."); return Environment.ExitCode; } }
上記プロジェクトをビルドする.以下に結果が出力される
dotnet publish Migration.csproj --configuration Release -r linux-x64
プロジェクトフォルダ/bin/Release/net8.0/linux-x64/publish
ビルド結果を本番サーバーに配置する。
実行時に`DOTNET_ENVIRONMTNT`環境変数を読み込んで、どの設定ファイルの接続先を使用するかを選んでいるため、プログラム実行前に環境変数を渡してやる
export DOTNET_ENVIRONMENT="Production";
echo $DOTNET_ENVIRONMENT
./Migration
以上
他の記事はこちら