Dockerfile恢复数据库失败求助:Docker化API与数据库部署遇报错
问题修复方案与数据库加载方法
核心错误分析
- API容器错误调用SQL Server命令:你的API容器基于
aspnet:6.0镜像,该镜像不包含SQL Server服务及相关工具,执行/opt/mssql/bin/sqlservr和sqlcmd必然报错"命令未找到"。 - 数据库恢复逻辑位置错误:数据库恢复操作应该在SQL Server容器内执行,而非API容器。
- Docker Compose配置错误:
ENTRYPOINT被错误放置在networks节点下,完全无效;连接字符串环境变量写法不符合.NET规范,且未配置连接重试机制,无法应对SQL Server启动延迟。
分步修复方案
1. 修正API的Dockerfile
移除所有与SQL Server相关的命令,专注于构建和启动API:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 5192 ENV ASPNETCORE_URLS=http://+:5192 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY . . FROM build AS publish RUN dotnet publish "e-Res/e-Res.csproj" -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . COPY ./e-Res/Uploads/Images ./Uploads/Images ENTRYPOINT ["dotnet", "e-Res.dll"]
2. 编写数据库恢复脚本
在项目根目录创建restore-db.sh脚本,用于在SQL Server容器内执行备份恢复:
#!/bin/bash # 等待SQL Server完全启动(可根据实际情况调整等待时间) sleep 30s # 执行数据库恢复 /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'QWElkj132!' -Q " -- 查看备份文件内的逻辑文件名 RESTORE FILELISTONLY FROM DISK='/var/opt/mssql/backup/ERes.bak'; -- 恢复数据库,指定容器内的文件存储路径 RESTORE DATABASE eres FROM DISK='/var/opt/mssql/backup/ERes.bak' WITH MOVE 'ERes' TO '/var/opt/mssql/data/ERes.mdf', MOVE 'ERes_log' TO '/var/opt/mssql/data/ERes_log.ldf', REPLACE; "
给脚本添加执行权限:
chmod +x restore-db.sh
3. 修正Docker Compose配置
将数据库恢复逻辑移至SQL Server容器,修正环境变量和配置位置:
version: '3' services: eres-sql: image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu restart: unless-stopped environment: - ACCEPT_EULA=Y - SA_PASSWORD=QWElkj132! - MSSQL_PID=Developer ports: - 1401:1433 expose: - 1433 volumes: # 挂载本地备份文件到容器内的备份目录 - ./e-Res/ERes.bak:/var/opt/mssql/backup/ERes.bak # 挂载恢复脚本到容器 - ./restore-db.sh:/usr/src/app/restore-db.sh # 先启动SQL Server服务,再执行恢复脚本 command: bash -c "/opt/mssql/bin/sqlservr & /usr/src/app/restore-db.sh && wait" networks: - eresnet2022 eres-api: restart: unless-stopped build: context: . environment: # .NET环境变量需用双下划线替代冒号 - ConnectionStrings__DefaultConnection=Server=eres-sql,1433;Database=eres;User=sa;Password=QWElkj132!;ConnectRetryCount=5;ConnectRetryInterval=2 - ASPNETCORE_ENVIRONMENT=Development ports: - 5192:5192 networks: - eresnet2022 depends_on: - eres-sql networks: eresnet2022: driver: bridge
关键优化说明
- 数据库恢复逻辑:通过挂载备份文件和脚本,在SQL Server容器内完成恢复,避免跨容器操作的复杂性;
MOVE参数确保备份文件中的逻辑路径与容器内实际路径匹配,REPLACE参数允许覆盖已存在的数据库。 - 连接可靠性:API连接字符串添加了
ConnectRetryCount和ConnectRetryInterval参数,应对SQL Server启动慢于API的情况。 - 环境变量规范:将
ConnectionStrings:DefaultConnection改为ConnectionStrings__DefaultConnection,符合.NET在Docker环境下的环境变量解析规则。
内容的提问来源于stack exchange,提问作者e Res
相关产品推荐
相关产品推荐

