【问题标题】:Docker + mssql-server-linux: How to launch .sql file during build (from Dockerfile)Docker + mssql-server-linux:如何在构建期间启动 .sql 文件(来自 Dockerfile)
【发布时间】:2017-10-23 11:16:17
【问题描述】:

我正在尝试使用 MSSQL DB 创建自己的 Docker 映像以进行开发。它基于microsoft/mssql-server-linux 图像。在构建期间,我想将一些.sql 文件复制到容器中,然后运行这些脚本(以创建数据库模式、表、插入一些数据等)。我的Dockerfile 看起来像这样:

# use MSSQL 2017 image on Ubuntu 16.04
FROM microsoft/mssql-server-linux:2017-latest

# create directory within SQL container for database files
RUN mkdir -p /opt/mssql-scripts

# copy the database files from host to container
COPY sql/000_create_db.sql /opt/mssql-scripts

# set environment variables
ENV MSSQL_SA_PASSWORD=P@ssw0rd
ENV ACCEPT_EULA=Y

# run initial scripts
RUN /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'P@ssw0rd' -i /opt/mssql-scripts/000_create_db.sql

000_create_db.sql 的内容在我看来并不重要。

真正的问题是,当我尝试使用命令 docker build -t demo . 构建此 Dockerfile 时,我总是会收到以下错误:

Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login timeout expired.
Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : TCP Provider: Error code 0x2749.
Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..

但是当我删除最后一个命令(运行初始脚本)时,构建并运行映像,然后像这样调用相同的命令:

docker build -t demo .
docker run -p 1433:1433 --name mssql -d demo
docker exec -it mssql "bash"
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'P@ssw0rd' -i /opt/mssql-scripts/000_create_db.sql

然后一切顺利。为什么我不能从Dockefile 运行脚本?

【问题讨论】:

    标签: sql-server docker dockerfile sqlcmd


    【解决方案1】:

    我最终使用了 VDR 解决方案的略微修改版本,它通过检查日志而不是休眠 10 秒来等待 sqlservr 启动:

    RUN ( /opt/mssql/bin/sqlservr --accept-eula & ) | grep -q "Service Broker manager has started" \
        && /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'P@ssw0rd' -i /opt/mssql-scripts/000_create_db.sql \
        && pkill sqlservr 
    

    【讨论】:

    • 成功了,非常感谢!我也可以使用 -q 参数执行 sqlcmd。
    • 我不得不稍微更新一下。如果 SQLServer 无法启动,则很难诊断。 RUN ( /opt/mssql/bin/sqlservr & ) | grep -q "Service Broker manager has started" && ( echo "SQLServer started" && sleep 10s ) || ( echo "SQLSERVER failed to start" && exit )
    【解决方案2】:

    从 mssql-server-linux dockerfile,看起来 mssql 是在 docker run 上启动的,所以你必须修改你的 dockerfile 中的最后一个“RUN”命令以在后台启动 sql-server,运行你的 sql 文件并停止 sql-server。

    RUN /opt/mssql/bin/sqlservr --accept-eula & sleep 10 \
        && /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'P@ssw0rd' -i /opt/mssql-scripts/000_create_db.sql \
        && pkill sqlservr 
    

    【讨论】:

      【解决方案3】:

      当你构建镜像时,主进程没有运行吃。在您的情况下,主要进程是SQL Server

      只有当你使用命令docker run ...启动容器时,进程才会运行

      你可以在这个阶段进行数据库初始化。 microsoft/mssql-server-linux Dockerfile 包含一些提示

      将所有 SQL Server 运行时文件从 build drop 复制到映像中。 复制./安装/

      只需将构建阶段的初始化脚本复制到./install 目录,它将被执行到启动阶段。

      【讨论】:

      • 对不起,但现在我真的很困惑。您在“主要流程”下是什么意思?你在说什么阶段?这是否意味着在构建映像期间不会触发来自 Dockerfile 的某些命令?但不是在运行容器期间触发它们吗?根据您的建议,我了解到我唯一需要做的就是创建一个名为“install”的目录并将 .sql 文件放入其中。但这对我不起作用。
      • 我认为@bukharov-sergey 误解了该特定 COPY 命令的意义。我相信它在 mssql-server-linux dockerfile 中,因为这是 Mircrosoft 用来将实际的 sql server 可执行文件复制到 mssql-server-linux docker 映像中的命令,然后我们都从 Docker Hub 下载该映像。跟你的东西没关系。将您自己的脚本复制过来作为一项单独的任务,由您在自己的基于 microsoft/mssql-server-linux 映像的 dockerfile 中完成。
      猜你喜欢
      • 2017-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 2017-04-16
      • 1970-01-01
      相关资源
      最近更新 更多