Docker Compose部署SQL Server时@@SERVERNAME显示异常求助
解决Docker Compose部署SQL Server容器时@@SERVERNAME显示异常的问题
问题现象
使用docker run并通过-h或--hostname参数启动SQL Server 2022/2019容器时,@@SERVERNAME能正常显示设置的主机名;但通过Docker Compose部署时,该值却显示为buildkitsandbox,尽管容器内/etc/hosts和/etc/hostname文件内容均正确。
原因分析
问题根源在镜像构建阶段:当前Dockerfile通过RUN指令启动SQL Server并执行初始化脚本,而Docker BuildKit构建镜像时,该RUN步骤会在名为buildkitsandbox的沙盒环境中运行,此时SQL Server会将沙盒主机名注册到系统元数据中。后续用Compose启动容器时,即使主机名已修改,SQL Server也不会自动更新@@SERVERNAME——这个值是SQL Server第一次启动时初始化并固定的。
解决方案
方法一:延迟初始化到容器启动阶段(推荐)
将初始化脚本的执行从镜像构建阶段移到容器启动阶段,确保SQL Server启动时已经使用Compose设置的主机名。
修改后的Dockerfile
FROM mcr.microsoft.com/mssql/server:2022-latest ENV ACCEPT_EULA=Y ENV SA_PASSWORD=dev1234# ENV MSSQL_PID=Developer ENV MSSQL_TCP_PORT=1433 ENV MSSQL_AGENT_ENABLED=True ENV MSSQL_ENABLE_HADR=1 WORKDIR /src RUN mkdir /var/opt/mssql/backup/ RUN mkdir /tmp/certificates/ RUN mkdir /tmp/scripts/ COPY ./cert/* /tmp/certificates/ COPY *.sql /tmp/scripts/ COPY entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["/opt/mssql/bin/sqlservr"]
创建entrypoint.sh启动脚本
#!/bin/bash # 后台启动SQL Server /opt/mssql/bin/sqlservr --accept-eula & SQL_PID=$! # 等待SQL Server完全启动 until /opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -P"$SA_PASSWORD" -Q "SELECT 1" > /dev/null 2>&1; do echo "等待SQL Server启动..." sleep 5 done # 执行初始化SQL脚本 /opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -P"$SA_PASSWORD" -i /tmp/scripts/setup.sql # 等待SQL Server进程持续运行 wait $SQL_PID
这样,SQL Server会在容器启动、主机名已正确设置后再完成初始化,@@SERVERNAME会自动注册为Compose指定的主机名。
方法二:容器启动后手动更新(临时方案)
如果无法修改镜像,可在Compose启动容器后,手动执行SQL命令更新服务器名称:
- 进入目标容器:
docker exec -it sqlNode1 bash
- 执行SQL命令更新服务器名称(替换
sqlNode1为对应容器的主机名):
/opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -Pdev1234# -Q " sp_dropserver 'buildkitsandbox'; GO sp_addserver 'sqlNode1', local; GO "
- 重启SQL Server服务:
# 单用户模式启动后关闭,再正常启动 /opt/mssql/bin/sqlservr -m -f & sleep 5 pkill sqlservr /opt/mssql/bin/sqlservr
验证方法
进入容器执行以下命令,确认@@SERVERNAME显示正确:
/opt/mssql-tools/bin/sqlcmd -S127.0.0.1 -Usa -Pdev1234# -Q "SELECT @@SERVERNAME"
内容的提问来源于stack exchange,提问作者Iulian Olteanu
相关产品推荐
相关产品推荐

