挂载/var/opt/mssql卷导致SQL Server容器自定义Schema丢失
问题分析
从日志和操作场景来看,核心问题有两个:
- sqlcmd参数错误:SQL语句被识别为未知命令行选项,说明等待SQL Server启动的脚本中,调用sqlcmd时缺少
-Q参数来指定要执行的SQL语句,导致命令解析失败。 - 初始化时机失效:挂载空卷到
/var/opt/mssql后,SQL Server会重新初始化系统数据库,原教程的等待逻辑因参数错误提前终止,导致自定义脚本在SQL Server未完全就绪时执行,或直接跳过执行流程,最终预安装Schema未生成。
解决方案
1. 修复entrypoint.sh中的sqlcmd调用逻辑
修改容器启动脚本(entrypoint.sh)里的SQL Server就绪等待代码,确保用-Q参数传递SQL语句:
# 等待SQL Server就绪,修复参数错误 until /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "$MSSQL_SA_PASSWORD" -Q "SET NOCOUNT ON; SELECT SUM(state) FROM sys.databases" > /dev/null 2>&1 do echo "等待SQL Server启动..." sleep 5s done
要点:用
-Q明确指定执行的SQL语句,添加日志重定向避免冗余输出,用双引号包裹密码变量(适配含特殊字符的密码)。
2. 限定自定义脚本仅在首次初始化时运行
挂载卷后,只有当系统数据库文件不存在时才需要执行setup.sql,通过检查核心文件判断初始化状态:
# 检查是否为首次初始化SQL Server if [ ! -f /var/opt/mssql/data/master.mdf ]; then # 等待SQL Server完全初始化完成 until /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "$MSSQL_SA_PASSWORD" -Q "SELECT 1" > /dev/null 2>&1 do echo "等待SQL Server初始化完成..." sleep 5s done # 执行自定义Schema脚本 echo "开始执行初始化脚本..." /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "$MSSQL_SA_PASSWORD" -d master -i /usr/src/app/setup.sql echo "初始化脚本执行完成..." fi
替换
/usr/src/app/setup.sql为你容器内setup.sql的实际路径(需与Dockerfile中COPY的路径一致)。
3. 重新构建镜像并验证
- 修复脚本后重新构建镜像:
docker build -t mssql-custom .
- 删除已存在的旧卷(避免残留的系统数据库影响测试):
docker volume rm sqlvolume
- 启动容器并查看日志:
docker run --rm --user=root --platform linux/amd64 -d --name mssqlserver -p 1433:1433 -e "ACCEPT_EULA=Y" -e MSSQL_SA_PASSWORD=StrongPassw0rd -v sqlvolume:/var/opt/mssql mssql-custom docker logs mssqlserver
日志中出现"初始化脚本执行完成"字样,说明脚本已成功运行;重启容器后,可通过连接SQL Server验证Schema是否持久存在。
额外注意事项
- 确保setup.sql文件在容器内的权限正确,可在Dockerfile中添加
RUN chmod 644 /usr/src/app/setup.sql赋予可读权限。 - 若密码包含特殊字符,必须在环境变量中用双引号包裹,避免shell解析错误。
内容的提问来源于stack exchange,提问作者Luu Tuan Hoang
相关产品推荐
相关产品推荐

