SQL Server Docker容器在设置后停止

时间:2018-06-26 09:09:54

标签: sql-server docker

我正在尝试在Docker SQL Server映像上运行安装脚本

为此,我从mssql映像创建了一个Dockerfile

FROM microsoft/mssql-server-linux:2017-CU8

# Create directory to place app specific files
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Copy setup scripts
COPY  entrypoint.sh \
    ./

RUN chmod +x ./entrypoint.sh

CMD /bin/bash ./entrypoint.sh

entrypoint.sh中,我正在启动SQL Server,我想运行一些安装命令。

#!/bin/bash

#start SQL Server
/opt/mssql/bin/sqlservr &

echo 'Sleeping 20 seconds before running setup script'
sleep 20s

echo 'Starting setup script'

#run the setup script to create the DB and the schema in the DB
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P <MyPassWd> -d master -i setup.sql

echo 'Finished setup script'

当我运行此脚本时,数据库启动,安装程序运行,然后 设置完成后,容器将关闭。

所以我认为脚本中的某些内容会导致容器关闭,因此我将脚本剥离到最低限度

#!/bin/bash

#start SQL Server
/opt/mssql/bin/sqlservr &

echo 'Sleeping 20 seconds before running setup script'
sleep 20s

这也将在sleep 20s完成之后停止容器。

继续...

#!/bin/bash

#start SQL Server
/opt/mssql/bin/sqlservr &

哪个会立即停止容器

然后...

#!/bin/bash

#start SQL Server
/opt/mssql/bin/sqlservr

现在容器可以运行了,但是我无法进行任何初始化

有人知道如何使它工作吗?

5 个答案:

答案 0 :(得分:3)

将sql服务器的密码更改为足够复杂。

docker run -d -p 1433:1433 -e "sa_password=ComplexPW2019!" -e "ACCEPT_EULA=Y" <sqlserverimageid>

答案 1 :(得分:0)

此问题的根本原因是为Docker容器分配了PID1。

PID 1将分配给Dockerfile中CMD中给定的命令(在我们的示例中是./entrypoint.sh)

容器根据PID 1发出垃圾邮件(一旦PID 1停止/被杀死的容器将被停止)

1)如果是/ opt / mssql / bin / sqlservr&
子进程ID将分配给sqlserver cmd,并将在后台执行,一旦脚本的其余部分执行完毕,容器将停止。

2)如果是/ opt / mssql / bin / sqlservr
该执行完成之前,脚本不会从此处继续执行。

因此解决方案是将PID 1分配给CMD / opt / mssql / bin / sqlservr,其余脚本应作为子进程执行。

我做了以下更改,它对我有用。

在Dockerfile中

replace CMD /bin/bash ./entrypoint.sh to CMD exec /bin/bash entrypoint.sh

在entrypoint.sh

   #!/bin/bash
   #start SQL Server
   sh -c " 
   echo 'Sleeping 20 seconds before running setup script'
   sleep 20s

   echo 'Starting setup script'

   #run the setup script to create the DB and the schema in the DB
   /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P \"YourStrong!Passw0rd\" -Q 
   \"ALTER LOGIN SA WITH PASSWORD='NewStrong!Passw0rd'\"

    echo 'Finished setup script'
    exit
    " & 
    exec /opt/mssql/bin/sqlservr

答案 2 :(得分:0)

SQL Server必须是最正确的命令。

我知道这没有意义,因为您希望先运行SQL Server,然后运行脚本来创建/还原数据库。我猜这是由于SQL Server在Linux上运行的方式(Sql服务器进程在启动时创建了一个SQL Server进程)。

MSDN文档在以下位置明确了执行顺序:https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-configure-docker?view=sql-server-ver15#customcontainer

因此,在您的示例中,您将必须编写以下内容:

/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P <MyPassWd> -d master -i setup.sql & /opt/mssql/bin/sqlservr

答案 3 :(得分:0)

有一个 pull request 允许在第一次运行时运行 init SQL 脚本。

<块引用>

此 PR 的目的是在 start.ps1 中添加检查文件夹 docker-entrypoint-initdb 并在其中运行所有 sql 脚本的功能。完成后,脚本会创建一个标志文件,以避免在停止后的下次启动时运行设置阶段。

<块引用>

通过将卷从本地文件夹脚本安装到 c:/docker-entrypoint-initdb,容器将执行所有 .sql 脚本文件。卷应该是一个目录。

例如

version: "3.8"
services:
  sqlserver:
    platform: windows/amd64
    environment: 
      - sa_password=<YourPassword>
      - ACCEPT_EULA=Y
    image: microsoft/mssql-server-windows-developer
    volumes: 
      - ./dockerfiles/sqlserver/initdb:c:/docker-entrypoint-initdb:ro
    ports:
      - "1433:1433"

答案 4 :(得分:0)

要在启动时创建数据库,请尝试以下方法。

Dockerfile

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA Y
ENV DB_NAME test
COPY startup.sh /var/opt/mssql/startup.sh
CMD ["bash", "/var/opt/mssql/startup.sh"]

startup.sh

#!/usr/bin/env bash
if ! [ -f /var/opt/mssql/.initialized ] && [ -n "$DB_NAME" ]; then
  while ! </dev/tcp/localhost/1433 2>/dev/null; do
    sleep 2
  done
  echo "Creating $DB_NAME database..."
  /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "$SA_PASSWORD" -d master \
    -Q "CREATE DATABASE $DB_NAME"
  touch /var/opt/mssql/.initialized
fi &
/opt/mssql/bin/sqlservr