简体   繁体   中英

Run database migration before app start (.NET5, EF core 5)

I have web and api applications. Running migrations inside Startup.cs doesn't seem like good idea because migration needs to be run once and my API and WEB projects are deployed at the same time.

Apps are .NET core web and .NET core api, docker images are created and they are running on linux.

I created .net core exe application that does migration but I don't know best way to incorporate it in this scenario.

My idea is to run that dll before docker web image starts but again problem is that I have two docker images

Or maybe create docker image from that migration console app and start web and api containers only if success

EDIT:

I created docker image using this docker file

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src

COPY ["ef-migrations-cli/EfMigrationsCLI/EfMigrationsCLI/EfMigrationsCLI.csproj", "ef-migrations-cli/EfMigrationsCLI/EfMigrationsCLI/"]

RUN dotnet restore "ef-migrations-cli/EfMigrationsCLI/EfMigrationsCLI/EfMigrationsCLI.csproj"  --source "https://api.nuget.org/v3/index.json"
COPY . .

WORKDIR /src
COPY ["RED.Database.Server/RED.Database.Server.csproj", "RED.Database.Server/"]

COPY . .


WORKDIR "/src/ef-migrations-cli/EfMigrationsCLI/EfMigrationsCLI"
FROM build AS publish
RUN dotnet publish "EfMigrationsCLI.csproj" -c Release -o /app/publish

WORKDIR /src
WORKDIR "/src/RED.Database.Server"
FROM build AS publish2
RUN find /src/RED.Database.Server/RED.Database.Server.csproj -name *.csproj
RUN dotnet publish "/src/RED.Database.Server/RED.Database.Server.csproj" -c Release -o /app/publish

FROM base AS final

WORKDIR /app

COPY --from=publish2 /app/publish .

COPY --from=publish /app/publish .

ENV Server "please_set_Server_env_variable_when_docker_run"
ENV DatabaseName "please_set_DatabaseName_env_variable_when_docker_run"
ENV UserId "please_set_UserId_env_variable_when_docker_run"
ENV Password "please_set_Password_env_variable_when_docker_run"
ENV DatabaseContext "REDDatabaseContext"
ENV MigrationsAssembly "RED.Database.Server.dll"

ENTRYPOINT [ "sh", "-c", "dotnet EfMigrationsCLI.dll --userid=${UserId} --password=${Password} --databasename=${DatabaseName} --server=${Server} --databaseContext=REDDatabaseContext --migrationsAssembly=${MigrationsAssembly}" ]

What I don't like is that migrations.dll and my app's dll that contains migrations are in same image.

How to separate them? Build one universal migrator image that all projects will use and then created separate image that loads that one and that builds necessary myappsthatcontainsmigration.dll file and pass that file to first created container

Running migrations as part of application startup is not something we recommend because of both this kind of concurrency issue and the need for permissions that may not be appropriate for the normally running application. We would recommend that database migration happen as part of application deployment, rather than first run. The deployment may use scripts (eg generated from migrations) or may run tools directly against the production database. In either case, it is done in a controlled manner to avoid concurrency and in an environment with appropriate permissions.

Github Issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM