我正在尝试在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
现在容器可以运行了,但是我无法进行任何初始化
有人知道如何使它工作吗?
答案 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