如何在Windows容器中通过Docker Compose初始化SQL Server数据库?
解决Windows版SQL Server Docker镜像初始化数据库的问题
我之前在Windows环境下用Docker Compose部署SQL Server Express镜像时,也碰到过和你一样的问题——直接用command指令跑初始化脚本根本没效果。后来研究了一下Windows版镜像的启动逻辑,终于找到可行的方案,分享给你:
为什么直接用command不行?
Windows版的microsoft/mssql-server-windows-express镜像默认启动命令是sqlservr.exe,如果直接用command替换成执行脚本的命令,会跳过镜像自带的SQL Server初始化流程,导致脚本执行时SQL服务还没就绪,甚至容器启动后直接退出。
正确的解决步骤
1. 准备初始化脚本和启动批处理
首先需要两个文件:
- 初始化SQL脚本(比如
init-db.sql):写好你要执行的数据库创建、表结构初始化等逻辑-- 示例:创建自定义数据库和表 CREATE DATABASE MyCustomDB; USE MyCustomDB; CREATE TABLE Users ( Id INT IDENTITY(1,1) PRIMARY KEY, UserName NVARCHAR(50) NOT NULL, Email NVARCHAR(100) NOT NULL ); - 启动批处理文件(比如
start-sql.cmd):负责启动SQL Server、等待服务就绪、执行初始化脚本,最后保持容器运行@echo off echo Starting SQL Server... :: 启动SQL Server进程(后台运行) sqlservr.exe & echo Waiting for SQL Server to be ready... :: 循环检查SQL服务是否可用,直到连接成功 :WAIT_LOOP sqlcmd -S localhost -U sa -P %SA_PASSWORD% -Q "SELECT 1" >nul 2>&1 IF %ERRORLEVEL% NEQ 0 ( timeout /t 10 /nobreak >nul GOTO WAIT_LOOP ) echo Executing initialization script... :: 执行初始化SQL脚本 sqlcmd -S localhost -U sa -P %SA_PASSWORD% -i C:\init-db.sql echo Initialization completed. Keeping container running... :: 保持容器不退出(等待无限时间) waitfor infinity
2. 修改Docker Compose配置
把这两个文件挂载到容器里,然后通过command指定运行我们的批处理文件,同时保留必要的环境变量:
myscustomservice: image: myscustomservice build: context: .\myscustomservice dockerfile: Dockerfile depends_on: - db # 确保服务依赖数据库,保证启动顺序 db: image: microsoft/mssql-server-windows-express environment: SA_PASSWORD: "YourStrong!Passw0rd" # 记得用符合要求的强密码 ACCEPT_EULA: "Y" volumes: # 把本地脚本目录挂载到容器的C盘根目录 - ./db-scripts/init-db.sql:C:\init-db.sql - ./db-scripts/start-sql.cmd:C:\start-sql.cmd command: cmd /c C:\start-sql.cmd ports: - "1433:1433"
3. 关键注意事项
- 密码必须符合SQL Server的要求:至少8位,包含大写字母、小写字母、数字和特殊字符
- 本地的
db-scripts文件夹要和docker-compose.yml在同一层级,或者调整挂载路径为你实际的路径 - 等待服务就绪的逻辑可以根据需要调整,比如把
timeout /t 10改成更短或更长的时间 - 如果你的自定义服务需要连接数据库,记得加上
depends_on,但注意这只是保证启动顺序,不保证数据库完全就绪,服务端最好也加连接重试逻辑
排查问题的小技巧
如果脚本还是没执行,试试这些方法:
- 查看容器日志:
docker logs <你的db容器ID>,看有没有报错信息 - 进入容器检查文件是否挂载成功:
docker exec -it <容器ID> cmd,然后执行dir C:\看脚本是否存在 - 手动在容器里执行脚本测试:
docker exec <容器ID> sqlcmd -S localhost -U sa -P YourStrong!Passw0rd -i C:\init-db.sql
内容的提问来源于stack exchange,提问作者Patrice Cote




