You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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

火山引擎 最新活动