Docker Compose部署MSSQL执行SQL超时,如何在服务启动后执行SQL?
解决SQL Server容器启动后执行初始化SQL的问题
你完全猜对了问题所在——当你直接在command里写sqlcmd命令时,容器启动后会立刻执行这个命令,而此时SQL Server实例还在启动过程中,根本没准备好接受连接,所以才会出现登录超时的错误。
下面是两种可靠的解决方案,帮你在SQL Server完全就绪后执行初始化SQL:
方案一:自定义启动脚本(推荐)
创建一个包含等待逻辑的shell脚本,让它先启动SQL Server,等待服务就绪后再执行你的初始化命令。
步骤1:编写初始化脚本
在项目目录下创建init-db.sh文件,内容如下:
#!/bin/bash set -e # 启动SQL Server服务到后台 /opt/mssql/bin/sqlservr & # 循环等待SQL Server就绪 echo "正在等待SQL Server启动..." until /opt/mssql-tools/bin/sqlcmd -U sa -P "$SA_PASSWORD" -Q "SELECT 1" > /dev/null 2>&1; do sleep 2 done # 执行你的初始化SQL命令 echo "SQL Server已就绪,开始执行初始化操作..." /opt/mssql-tools/bin/sqlcmd -U sa -P "$SA_PASSWORD" -Q "SELECT [name] FROM sys.databases" # 如果有多个SQL脚本文件,可以用下面的循环批量执行 # for sql_file in /docker-entrypoint-initdb.d/*.sql; do # echo "执行脚本: $sql_file" # /opt/mssql-tools/bin/sqlcmd -U sa -P "$SA_PASSWORD" -i "$sql_file" # done # 等待后台的SQL Server进程,保持容器运行 wait
步骤2:给脚本添加执行权限
在终端运行:
chmod +x init-db.sh
步骤3:修改docker-compose.yml
挂载脚本并设置为容器的entrypoint:
services: tmp-db: image: microsoft/mssql-server-linux:latest environment: ACCEPT_EULA: Y SA_PASSWORD: yourStrong(!)Password entrypoint: /init-db.sh volumes: - ./init-db.sh:/init-db.sh # 如果有单独的SQL脚本文件,挂载到容器内的目录(对应脚本里的路径) # - ./sql-scripts:/docker-entrypoint-initdb.d ports: - 1433:1433
方案二:使用健康检查配合临时命令
如果你不想写自定义脚本,也可以利用Docker的健康检查功能,先确保SQL Server容器健康,再手动执行初始化命令:
修改docker-compose.yml添加健康检查
services: tmp-db: image: microsoft/mssql-server-linux:latest environment: ACCEPT_EULA: Y SA_PASSWORD: yourStrong(!)Password ports: - 1433:1433 healthcheck: test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -U sa -P yourStrong(!)Password -Q 'SELECT 1' || exit 1"] interval: 5s timeout: 10s retries: 5
启动容器后执行初始化命令
当容器状态变为healthy后,在终端运行:
docker-compose exec tmp-db /opt/mssql-tools/bin/sqlcmd -U sa -P yourStrong(!)Password -Q "SELECT [name] FROM sys.databases"
这种方法适合临时测试,但如果需要自动执行初始化,方案一更合适。
内容的提问来源于stack exchange,提问作者Serg046
相关产品推荐
相关产品推荐

