草庐IT

sql-server - SQL Server Linux 的 Docker 容器不断退出

coder 2023-06-21 原文

我想为 SQL Server Linux 修改容器的行为通过在容器启动时添加一个带有一张表的简单数据库

我看到此问题的 docker 镜像版本是 2017 年 5 月 20 日的最新版本,即 ctp2-1

我正在使用 Windows 版 Docker,最新版本为 17.05.0-ce。我将 MobyLinuxVM 的 RAM 增加到 6144MB,因为建议超过 4GB。

重现问题的步骤

准备文件

(1) Create a local Windows folder, in my case, 

    C:\temp\docker\

(2) Add "Dockerfile" (note no file extension) with the following content.

    FROM microsoft/mssql-server-linux:latest
    COPY ./custom /tmp
    RUN chmod +x /tmp/entrypoint.sh \
        && chmod +x /tmp/createdb.sh
    CMD /bin/bash /tmp/entrypoint.sh

(3) Add a subfolder "custom"

    C:\temp\docker\custom\

(4) Add 3 files to "custom" subfolder with following content.

   (A) entrypoint.sh
    /opt/mssql/bin/sqlservr & /tmp/createdb.sh

   (B) createdb.sh
    sleep 30s
    /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P '!StrongPass45' -d master -i /tmp/createdb.sql

   (C) createdb.sql
    CREATE DATABASE DemoData;
    GO
    USE DemoData;
    GO
    CREATE TABLE Products (ID int, ProductName nvarchar(max));
    GO

运行 DOCKER 命令(您将在此处的最后一步看到问题)

(1) Open PowerShell and cd to folder in step (1) above, in my case

    cd C:\temp\docker

(2) Run docker build command

    docker build .

(3) After image is built, run the following command and remember the first 3 letters of your image id, in my case "e65"

    docker images

    [![enter image description here][2]][2]

(4) Create the container with the following command (note the last 3 characters should be replaced by yours, also use the same password you used above)

    docker run -d -e SA_PASSWORD="!StrongPass45" -e ACCEPT_EULA="Y" -p 1433:1433 e65

(5) Check your container is running

    docker ps -a

  [![enter image description here][2]][2]

(6) Wait about 2 minutes and check your container status again. AT THIS POINT, THE CONTAINER WOULD HAVE EXITED.

   docker ps -a

   [![enter image description here][2]][2]

我查看了日志如下。

docker logs e65

下面是 SQL Server 成功创建 DemoData 数据库后的日志底部部分。

[![enter image description here][2]][2]

IMO,日志中的问题行就是这个

Parallel redo is shutdown for database 'DemoData' with worker pool size [1].

我已经尝试了各种其他 SQL 语句(甚至添加自定义 MDF 和 LDF 文件并附加到它们)来向 OOB 图像添加行为。 我什至能够在容器退出前使用 SSMS 连接到新数据库几秒钟!

有人见过这个问题吗?有人可以试一试吗?

最佳答案

有效的解决方案

根据我收到的反馈,很明显 Dockerfile 的 CMD 正在返回。以下是解决问题的完整步骤。

[如果您找到了一个更可靠的解决方案,它不依赖于我在该解决方案中编写的特定超时值,以允许 SQL Server 在容器启动时自行引导,请告诉我]

准备文件

(1) 创建本地 Windows 文件夹,在我的例子中,

C:\temp\docker\

(2) 添加“Dockerfile”(注意没有文件扩展名),内容如下。

FROM microsoft/mssql-server-linux:latest
COPY ./custom /tmp
RUN chmod +x /tmp/entrypoint.sh
CMD /bin/bash /tmp/entrypoint.sh

(3) 添加子文件夹“custom”

C:\temp\docker\custom\

(4) 添加2个文件到“custom”子文件夹如下。

入口点.sh

#!/bin/bash

set -e
run_cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P HdkPKD57%@6876^ -l 30 -d master -i /tmp/createdb.sql"

>&2 echo "Allowing 30 seconds for SQL Server to bootstrap, then creating database.."
until $run_cmd & /opt/mssql/bin/sqlservr; do
>&2 echo "This should not be executing!"
done

createdb.sql

CREATE DATABASE DemoData;
GO
USE DemoData;
GO
CREATE TABLE Products (ID int, ProductName nvarchar(max));
GO

运行 DOCKER 命令

(A) 在我的例子中,打开 PowerShell 并 cd 到上面步骤 (1) 中的文件夹

cd C:\temp\docker

(B) 运行 docker build 命令

docker build .

(C) 构建图像后,获取图像的前 3 个字符,在我的例子中是 086

docker images

(D) 使用正确的镜像id和密码创建容器

docker run -d -e 'SA_PASSWORD=HdkPKD57%@6876^' -e 'ACCEPT_EULA=Y' -p 1433:1433 086

(E) 检查您的容器是否正在运行

docker ps -a

这个容器不会退出!创建预期的数据库“DemoData”。问题解决了!

docker logs 2aa 命令(2aa 是我的容器 ID,你的会不同)显示干净的构建,没有错误或警告。日志开始如下

Allowing 30 seconds for SQL Server to bootstrap, then creating database..
This is an evaluation version.  There are [173] days left in the evaluation period.
2017-05-21 17:39:50.69 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
....

结束如下。

2017-05-21 17:39:54.20 spid51      Starting up database 'DemoData'.
2017-05-21 17:39:54.43 spid51      Parallel redo is started for database 'DemoData' with worker pool size [1].
2017-05-21 17:39:54.44 spid51      Parallel redo is shutdown for database 'DemoData' with worker pool size [1].
2017-05-21 17:39:54.51 spid7s      Recovery is complete. This is an informational message only. No user action is required.
Changed database context to 'DemoData'.

连接 SSMS

我能够使用 SSMS 成功连接到这个数据库,如下所示(IP 地址 10.0.75.1 是包含容器的 docker 主机的 IP 地址)

重要提示

  • sqlcmd SA 密码

    sqlcmd 是用于运行 dbcreate.SQL 和创建数据库 DemoData 的实用程序。该实用程序在 Linux 上使用 ODBC 驱动程序,并且对您如何指定开关值很敏感,尤其是密码 -P

    避免登录相关问题found hereexplained here , 请仔细选择您的强密码,并在 -P 下的 entrypoint.sh 中指定它,不要用 双引号单引号[]。请参见上面的 (4)

    此外,此密码必须与您传递给容器的 docker run 环境变量相匹配。请参阅上面的 (D) 以避免密码不匹配。

    详细documentation on sqlcmd is here .

  • sqlcmd 登录超时

    请注意我如何使用 -l 开关为 entrypoint.sh 文件中的 sqlcmd 指定登录超时 30 秒。这是我避免 CMD 返回(这使得容器退出)的解决方案的症结所在。此超时时间足够长,足以让 SQL 服务器启动。

关于sql-server - SQL Server Linux 的 Docker 容器不断退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44092281/

有关sql-server - SQL Server Linux 的 Docker 容器不断退出的更多相关文章

  1. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  2. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  3. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  4. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  5. sql - 在 Rails Console for PostgreSQL 的表中显示数据 - 2

    我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有

  6. ruby-on-rails - rails : uninitialized constant just happen on production server - 2

    我有一个放在lib/network中的类:moduleNetworkApiclassNetworkProxyendend然后在另一个类中,我引用了这个类:network_proxy=::NetworkApi::NetworkProxy.new(params)一切都在我的开发环境中正常运行,但是当我部署到服务器时,我在上面一行收到错误消息:NameError:uninitializedconstantNetworkApi::NetworkProxy我不知道为什么会出现这个奇怪的错误。请告诉我为什么。 最佳答案 请注意Rails5dis

  7. ruby - 防止SQL注入(inject)/好的Ruby方法 - 2

    Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject

  8. ruby-on-rails - 如何在 Rails 中的不同数据库上执行直接 SQL 代码 - 2

    我正在编写一个Rails应用程序,它将监视某些特定数据库的数据质量。为了做到这一点,我需要能够对这些数据库执行直接SQL查询——这当然与用于驱动Rails应用程序模型的数据库不同。简而言之,这意味着我无法使用通过ActiveRecord基础连接的技巧。我需要连接的数据库在设计时是未知的(即:我不能将它们的详细信息放在database.yaml中)。相反,我有一个模型“database_details”,用户将使用它来输入应用程序将在运行时执行查询的数据库的详细信息。因此与这些数据库的连接实际上是动态的,细节仅在运行时解析。 最佳答案

  9. sql - Rails:使用 Postgres 创建对象时重复 ActiveRecord::RecordNotUnique? - 2

    我正在使用Rails4应用程序,它需要创建大量对象以响应来自另一个系统的事件。当我调用create!时,主键列上出现非常频繁的ActiveRecord::RecordNotUnique错误(由PG::UniqueViolation引起)我的模型之一。我在SO上找到了其他答案,建议挽救异常并调用retry:beginTableName.create!(data:'here')rescueActiveRecord::RecordNotUnique=>eife.message.include?'_pkey'#Onlyretryprimarykeyviolationslog.warn"Retr

  10. ruby-on-rails - Ruby 和 SQL 中的重复业务逻辑 - 2

    我有一个PORO(普通旧Ruby对象)来处理一些业务逻辑。它接收一个ActiveRecord对象并对其进行分类。为了简单起见,以下面为例:classClassificatorSTATES={1=>"Positive",2=>"Neutral",3=>"Negative"}definitializer(item)@item=itemenddefnameSTATES.fetch(state_id)endprivatedefstate_idreturn1if@item.value>0return2if@item.value==0return3if@item.value但是,我还想根据这些st

随机推荐