构建Docker镜像时sqlcmd无法连接Microsoft SQL Server是什么原因?
构建Docker镜像时sqlcmd调用超时的根本原因
核心问题出在Docker镜像的构建逻辑和MSSQL官方镜像的运行机制上:
- MSSQL官方镜像仅在**容器启动阶段(执行docker run时)**才会通过内置的ENTRYPOINT/CMD指令启动sqlservr数据库进程,镜像构建阶段的所有RUN指令执行时,不会自动启动数据库服务。
- 你在Dockerfile中调用sqlcmd的RUN步骤是在独立的临时构建容器中执行的,此时环境中没有运行的SQL Server实例,无论怎么修改连接地址、增加等待时长都无法建立连接,必然返回超时、网络不可达类错误。
你后续把sqlcmd步骤移到容器启动后执行可以成功,正是因为此时容器已经完成启动流程,SQL Server服务处于正常运行状态。
可行的内置初始化方案
如果需要将初始化逻辑内置到镜像中,不需要每次启动容器后手动执行脚本,可以用以下两种方案:
方案1:启动时自动执行初始化(推荐)
将初始化脚本拷贝到镜像内,重写镜像的ENTRYPOINT为自定义脚本:
- 自定义启动脚本内先后台启动SQL Server进程
- 循环检测SQL Server服务就绪状态,就绪后执行
init_script_core.sql - 脚本执行完成后,前台挂起SQL Server进程,保证容器正常运行
方案2:构建阶段完成数据初始化
如果需要将初始化后的数据库文件直接打进镜像层,可以在RUN指令内按顺序执行操作:
RUN ( /opt/mssql/bin/sqlservr & ) | grep -q "Service Broker manager has started" \ && sqlcmd -S localhost -U SA -P $SA_PASSWORD -i /tmp/init_script_core.sql \ && pkill sqlservr
上述指令会先后台启动SQL Server,等待服务启动完成的日志输出后执行初始化脚本,执行完成后主动停止SQL Server进程,保证构建层可以正常提交。
内容的提问来源于stack exchange,提问作者Westerlund.io
相关产品推荐
相关产品推荐

