如何在Ubuntu环境中构建并部署SqlProj项目
解决Ubuntu环境下构建部署SqlProj项目的问题
我明白你现在的困境:SSDT的MSBuild目标文件确实是Windows专属的,Linux上的dotnet msbuild根本找不到这些依赖,所以直接跑肯定会报MSB4019错误。不过不用放弃SqlProj管理数据库对象的方式,这里有几个可行的替代方案,帮你把SqlProj纳入Ubuntu的CI/CD流程:
方案一:用Windows Docker容器在Ubuntu CI里构建SqlProj
既然SSDT只支持Windows,我们可以在Ubuntu的CI runner里启动一个Windows容器,用容器里的MSBuild+SSDT来构建SqlProj。这样既不用改现有SqlProj结构,又能在Linux环境的CI里运行。
步骤如下:
- 准备一个Dockerfile,基于微软的Windows .NET Framework构建镜像,安装SSDT:
FROM mcr.microsoft.com/dotnet/framework/build:4.8-windowsservercore-ltsc2019 RUN choco install sql-server-data-tools -y - 在CI脚本里,构建这个镜像(或者直接用预构建好的),把你的项目目录挂载到容器里,执行MSBuild命令:
docker run --rm -v "$(pwd):/src" your-ssdt-msbuild-image msbuild /src/YourProject.sqlproj /t:Build /p:Configuration=Release /p:SqlPublishProfilePath=YourPublishProfile.publish.xml - 这个方案的好处是完全保留你现有的SqlProj和发布配置,不需要修改任何代码;缺点是Windows容器在Linux上运行需要Docker Desktop或者支持WSL2的环境,CI runner得提前配置好。
方案二:预生成DacPac包,用Linux版SqlPackage部署
SqlPackage有官方的Linux版本,我们可以先在Windows环境(比如开发机或者CI的Windows节点)生成DacPac包,然后在Ubuntu上用SqlPackage来部署,这样避开在Linux上构建SqlProj的问题。
具体步骤:
- 在Windows上生成DacPac:
生成的DacPac文件在msbuild YourProject.sqlproj /t:Build /p:Configuration=Releasebin/Release目录下,你可以把它上传到CI的 artifacts,或者直接纳入Git(如果文件不大的话)。 - 在Ubuntu上安装SqlPackage:
dotnet tool install --global microsoft.sqlpackage - 用SqlPackage部署到SQL Server:
如果你有发布配置文件(sqlpackage /Action:Publish /SourceFile:YourProject.dacpac /TargetConnectionString:"Server=your-server;Database=your-db;User Id=your-user;Password=your-pass;".publish.xml),也可以用/Profile:YourProfile.publish.xml参数来指定,和Windows上的部署逻辑完全一致。这个方案的优点是部署环节完全跨平台;缺点是需要一个Windows环境来生成DacPac,不过很多CI系统(比如GitHub Actions、Azure DevOps)都支持混合节点,你可以加一个Windows步骤生成包,再用Ubuntu步骤部署。
方案三:迁移到DbUp/Flyway,保留原生SQL脚本
如果你想彻底摆脱Windows依赖,可以把SqlProj里的数据库对象(表、存储过程、索引、部署脚本)提取出来,用DbUp或者Flyway这类跨平台的数据库迁移工具来管理。这样既能保留原生SQL的编写方式,又能在Ubuntu的CI/CD里直接运行。
步骤示例(以DbUp为例):
- 从SqlProj里导出所有SQL对象到单独的
.sql文件,按迁移顺序命名(比如001_Create_Tables.sql、002_Add_StoredProcedures.sql、003_Post_Deployment_Script.sql)。 - 创建一个.NET Core控制台项目,安装DbUp NuGet包:
Install-Package DbUp。 - 在Program.cs里配置DbUp,把这些SQL脚本作为嵌入资源加载:
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING"); var upgrader = DeployChanges.To .SqlDatabase(connectionString) .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly()) .LogToConsole() .Build(); var result = upgrader.PerformUpgrade(); if (!result.Successful) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(result.Error); Console.ResetColor(); return -1; } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Success!"); Console.ResetColor(); return 0; - 在Ubuntu的CI/CD里,直接运行这个控制台项目:
dotnet run --project DbUpMigrationProject。
这个方案的优点是完全跨平台,不需要任何Windows依赖,而且迁移是增量式的,适合CI/CD的自动化流程;缺点是需要手动把SqlProj里的脚本迁移到单独的文件,不过这是一次性的工作,之后维护起来和SqlProj类似。
内容的提问来源于stack exchange,提问作者Brandon Avant
相关产品推荐
相关产品推荐

