如何在Docker SQL Server镜像上运行设置脚本?

7
我将尝试在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个回答

9

将SQL Server的密码更改为足够复杂。

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

那就是我遇到的问题。将密码更改为更复杂的一个解决了这个问题。 - ShadeToD

3

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

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

2
这个问题的根本原因是为docker容器分配PID 1。
在Dockerfile中给定的CMD命令将被分配给PID 1 (在我们的情况下是./entrypoint.sh)
容器的生命周期取决于PID 1(一旦PID 1停止/被杀死,容器将停止)
1) 在/opt/mssql/bin/sqlservr&amp;的情况下
子进程ID将被分配给sqlserver cmd并在后台执行,只要其余的脚本被执行,容器就会停止。
2) 在/opt/mssql/bin/sqlservr的情况下
脚本不会在此处继续执行,直到此执行完成为止。
因此,解决方案是将PID 1分配给CMD /opt/mssql/bin/sqlservr,并将剩余的脚本作为子进程执行。
我已经做了以下更改,对我有效。
在Dockerfile中
将CMD /bin/bash ./entrypoint.sh替换为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

0

有一个拉取请求,允许在第一次运行时运行初始化SQL脚本。

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

通过从本地文件夹脚本挂载卷到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"

0

SQL Server 必须是最右边的命令。

我知道这看起来没有意义,因为你想要先运行 SQL Server,然后再运行脚本来创建/还原数据库。我猜这是因为 SQL Server 在 Linux 上运行的方式(Sql server 进程在启动时创建一个 SQL server 进程)。

MSDN 文档在 https://learn.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

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