You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker构建异常:SQL Server容器退出与ASP.NET API迁移问题解决

问题解决指南

一、SQL Server容器意外退出的修复

原因分析

docker-compose中mssql服务的自定义命令将sqlservr放到后台运行,执行完初始化脚本和sleep后,脚本进程结束,容器因主进程退出而停止。

修复步骤

修改docker-compose.yml中mssql服务的command,让sqlservr作为前台进程运行,同时正确处理初始化脚本的执行:

services:
  mssql:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
      SA_PASSWORD: "YourStrong!Passw0rd"
      ACCEPT_EULA: "Y"
      MSSQL_PID: "Developer"
    ports:
      - "1433:1433"
    volumes:
      - mssqldata:/var/opt/mssql
      - ./mssql-init:/mssql-init
    command: >
      /bin/bash -c "
      # 启动SQL Server并记录进程ID
      /opt/mssql/bin/sqlservr &
      SQLPID=$!
      # 轮询等待SQL Server可用
      until /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'YourStrong!Passw0rd' -Q 'SELECT 1' 2>/dev/null; do
        sleep 1
      done
      # 执行数据库初始化脚本
      /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'YourStrong!Passw0rd' -i /mssql-init/init-database.sql
      # 等待主进程结束,防止容器退出
      wait $SQLPID"

二、ASP.NET API容器构建失败与迁移问题修复

问题1:迁移文件缺失导致build失败

原因分析

Dockerfile的final阶段仅复制了csproj和发布后的文件,未包含Visual Studio生成的迁移文件(通常在Migrations目录下),dotnet ef database update需要这些文件才能执行构建和迁移操作。

修复步骤

修改ASP.NET API的Dockerfile,在final阶段复制迁移目录:

# Use the SDK image to build and publish the app
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["PaymentAPI/PaymentAPI.csproj", "PaymentAPI/"]
RUN dotnet restore "PaymentAPI/PaymentAPI.csproj"
COPY . .
WORKDIR "/src/PaymentAPI"
RUN dotnet build "PaymentAPI.csproj" -c Release -o /app/build
RUN dotnet publish "PaymentAPI.csproj" -c Release -o /app/publish

# Use the SDK image to run the app and perform migrations
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS final
WORKDIR /app
COPY --from=build /app/publish .
# 复制迁移文件目录到容器
COPY --from=build /src/PaymentAPI/Migrations ./Migrations
COPY --from=build /src/PaymentAPI/PaymentAPI.csproj /app/
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh
RUN dotnet tool install --global dotnet-ef
ENV PATH="$PATH:/root/.dotnet/tools"
ENTRYPOINT ["./entrypoint.sh"]

问题2:API无法连接SQL Server容器

原因分析

API的数据库连接字符串若配置为localhost,在Docker容器环境中无法访问到mssql服务,需使用docker-compose中定义的服务名mssql作为数据库服务器地址。

修复步骤

修改API的appsettings.Development.json中的连接字符串:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=mssql;Database=PaymentDatabase;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True;"
  }
}

问题3:entrypoint脚本优化

原因分析

原脚本中dotnet ef database update的输出被重定向,难以排查具体错误,且未针对容器环境优化连接检查逻辑。

修复步骤

修改entrypoint.sh,增加清晰日志输出并优化连接检查:

#!/bin/bash
set -e

run_cmd="dotnet PaymentAPI.dll"

# 等待SQL Server容器可用
until /opt/mssql-tools/bin/sqlcmd -S mssql -U sa -P 'YourStrong!Passw0rd' -Q 'SELECT 1' 2>/dev/null; do
  >&2 echo "SQL Server is starting up, waiting..."
  sleep 2
done

>&2 echo "SQL Server is up - executing database migrations"
# 执行EF迁移
dotnet ef database update --project /app/PaymentAPI.csproj

>&2 echo "Migrations completed - starting API service"
exec $run_cmd

三、实现持续迁移机制

当前优化后的entrypoint脚本已包含dotnet ef database update步骤,只要迁移文件被正确复制到容器、连接字符串配置正确,每次API容器启动时都会自动检查并应用最新的迁移。

额外建议

  • 将迁移文件纳入版本控制,确保代码更新时迁移文件同步到容器中
  • 生产环境避免硬编码数据库密码,可使用Docker Secrets或环境变量管理敏感信息

内容的提问来源于stack exchange,提问作者Supernova-Ohee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:03:10