本番サーバーでEFCoreマイグレーション

本番サーバーで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

以上

他の記事はこちら

コメントする