如何将Docker镜像中的.NET Core数据库迁移工具与迁移项目拆分独立构建?
实现方案
第一步:构建独立的EF Core迁移工具基础镜像
该镜像仅包含稳定的迁移工具程序,迭代频率极低,构建一次可长期复用。
迁移工具专属Dockerfile(命名为Dockerfile.cli)
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" COPY . . WORKDIR "/src/ef-migrations-cli/EfMigrationsCLI/EfMigrationsCLI" RUN dotnet publish "EfMigrationsCLI.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app 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 "" ENV MigrationsAssembly "" # 入口点所有参数都通过环境变量动态读取,不硬编码业务配置 ENTRYPOINT [ "sh", "-c", "dotnet EfMigrationsCLI.dll --userid=${UserId} --password=${Password} --databasename=${DatabaseName} --server=${Server} --databaseContext=${DatabaseContext} --migrationsAssembly=${MigrationsAssembly}" ]
构建迁移工具镜像命令
docker build -t ef-migrations-cli:v1.0 -f Dockerfile.cli .
构建完成后可推送到私有镜像仓库存储,无需频繁更新。
第二步:业务迁移镜像构建/运行方案
提供两种常用方案适配不同场景:
方案1:基于迁移工具基础镜像构建业务专属迁移镜像(适合生产流水线)
仅打包业务迁移逻辑,构建速度快,和原有使用习惯完全兼容。
业务迁移Dockerfile(命名为Dockerfile.business)
# 构建业务迁移项目阶段 FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build WORKDIR /src COPY ["RED.Database.Server/RED.Database.Server.csproj", "RED.Database.Server/"] RUN dotnet restore "RED.Database.Server/RED.Database.Server.csproj" COPY . . WORKDIR "/src/RED.Database.Server" RUN dotnet publish "RED.Database.Server.csproj" -c Release -o /app/publish # 基于稳定的迁移工具基础镜像组装最终运行镜像 FROM ef-migrations-cli:v1.0 AS final WORKDIR /app # 仅复制业务迁移相关文件,不用重复打包迁移工具 COPY --from=build /app/publish . # 配置业务侧默认参数,运行时可覆盖 ENV DatabaseContext "REDDatabaseContext" ENV MigrationsAssembly "RED.Database.Server.dll"
构建业务迁移镜像命令
docker build -t red-db-migrate:v20240520 -f Dockerfile.business .
运行命令(和原有使用逻辑完全一致)
docker run -e Server=xxx -e DatabaseName=xxx -e UserId=xxx -e Password=xxx red-db-migrate:v20240520
方案2:运行时直接挂载业务迁移dll(适合临时测试/快速验证)
无需构建业务镜像,本地编译好业务迁移dll后直接挂载到迁移工具容器运行:
# 假设本地编译后的业务dll存放在当前目录的publish文件夹下 docker run -v $(pwd)/publish:/app/migrations \ -e Server=xxx \ -e DatabaseName=xxx \ -e UserId=xxx \ -e Password=xxx \ -e DatabaseContext=REDDatabaseContext \ -e MigrationsAssembly=migrations/RED.Database.Server.dll \ ef-migrations-cli:v1.0
内容的提问来源于stack exchange,提问作者Vlado Pandžić
相关产品推荐
相关产品推荐

