本番サーバーで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
以上
他の記事はこちら