在Docker上启动SQL Server后运行SQL脚本

17

我有一个Dockerfile,其中包含以下代码

FROM microsoft/mssql-server-windows-express
COPY ./create-db.sql .
ENV ACCEPT_EULA=Y
ENV sa_password=##$wo0RD!
CMD sqlcmd -i create-db.sql

我能够创建图像,但当我使用该图像运行容器时,由于脚本在 SQL Server 启动之前执行,因此我看不到已创建的数据库。

我能否使脚本在启动 SQL Server 服务后执行?


在启动Docker并使用来自主机(您的PC)的SSMS连接到Docker容器上的SQL Server之后,您可以运行脚本。或者您需要动态执行此操作? - Rigerta
3
我想要动态地完成它,因为我希望在运行容器后立即拥有具体数据库的 SQL Server。 - Art Base
对于 Docker 初学者,这里是如何在 Docker 中运行 SQL Server 的方法:https://thecodeframework.com/run-sql-server-inside-a-docker-container/ - Gagan
2个回答

14

RUN用于构建镜像的层,CMD是在启动构建图像的实例(“容器”)时运行的命令。

如果你的脚本依赖于这些环境变量,那么如果它是较旧版本的Docker,则可能会失败,因为这些变量不是按照你想要定义的方式定义的!

在较旧版本的docker中Dockerfile ENV命令使用空格而不是“=”

您的Dockerfile应该如下:

FROM microsoft/mssql-server-windows-express
COPY ./create-db.sql .
ENV ACCEPT_EULA Y
ENV SA_PASSWORD ##$wo0RD!
RUN sqlcmd -i create-db.sql 

这将创建一个包含数据库及其密码的映像。

(如果SQL文件使用环境变量,那么在复制之前更新SQL文件可能是没有意义的。) 如果您想在docker构建和docker运行步骤之间能够覆盖密码,请使用docker run --env sa_password=##$wo0RD! ...,您需要将最后一行更改为:

CMD sqlcmd -i create-db.sql && .\start -sa_password $env:SA_PASSWORD \
-ACCEPT_EULA $env:ACCEPT_EULA -attach_dbs \"$env:attach_dbs\" -Verbose

这是继承自上游镜像的修改版CMD命令行。


4
我目前正在运行入口脚本,这是在运行docker容器后执行的(使用mcr.microsoft.com/mssql/server:2017-latest)。但是,只有在构建时仅对数据进行一次填充是更好的解决方案。唯一的问题是,似乎无法访问数据库,我总是得到以下错误信息:Step 5/5 : RUN /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 13j1k23j1l3H! -d master -i db-init.sql ---> Running in 57452421d9d4 Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Login timeout expired. - rStorms
2
考虑到服务可能没有启动,这是有道理的,对吧?我该怎么解决呢? - rStorms
1
@rStorms,你解决了这个问题吗?我目前也遇到了同样的情况。 - Bin4ry
检查你的CMD...如果它只是运行并退出,那么你的容器也将只会运行并退出。 - dagelf
顺便提一下,SA_PASSWORD 必须是大写的。小写对我不起作用。 - SERAJ
显示剩余2条评论

8
您可以点击此链接 https://github.com/microsoft/mssql-docker/issues/11 查看详细内容。感谢Robin Moffatt.的贡献。请将您的docker-compose.yml文件更改为包含以下内容。
mssql:
image: microsoft/mssql-server-windows-express
environment: 
  - SA_PASSWORD=##$wo0RD!
  - ACCEPT_EULA=Y
volumes:
 # directory with sql script on pc to /scripts/
 # - ./data/mssql:/scripts/
  - ./create-db.sql:/scripts/
command:
  - /bin/bash
  - -c 
  - |
    # Launch MSSQL and send to background
    /opt/mssql/bin/sqlservr &
    # Wait 30 seconds for it to be available
    # (lame, I know, but there's no nc available to start prodding network ports)
    sleep 30
    # Run every script in /scripts
    # TODO set a flag so that this is only done once on creation, 
    #      and not every time the container runs
    for foo in /scripts/*.sql
      do /opt/mssql-tools/bin/sqlcmd -U sa -P $$SA_PASSWORD -l 30 -e -i $$foo
    done
    # So that the container doesn't shut down, sleep this thread
    sleep infinity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接