Bootstrapsystemdatadirectories()失败(Hresult 0x8007010b)

发布于 2025-02-05 17:33:22 字数 3472 浏览 2 评论 0原文

试图将DB安装到MSSQL Docker容器

Dockerfile

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP@ssw0rd!
ENV MSSQL_TCP_PORT=1433
EXPOSE 1433

COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf

ENTRYPOINT /opt/mssql/bin/sqlservr

编辑

看来,唯一阻止图像作为容器运行的东西是当我在dockerfile中添加这两个复制指令时。当我删除两个复制时,一切正常。

实际上,它说它不能复制c:\ tempdata \ master.mdf /var/opt/mssql/data/master.master.mdf。但是为什么?

最近,什么时候

结构

所有文件都位于我本地计算机上的同一文件夹中。

myfolder
    /Dockerfile
    /mydb.mdf
    /mydb_log.ldf 

环境

  • Windows 10用于工作站

  • Docker Desktop 4.5.1(74721)(

    发动机20.10.12,

    组成1.29.2,

    kubernetes 1.22.5,

    Snyk 1.827.0,

    凭证辅助辅助器0.6.4)

  • 式辅助式工作室代码1.67.2

获得的错误

以完美的方式构建,让相信一切都很好。但是,当我运行它时,我会收到一个错误:

ERROR: BootstrapSystemDataDirectories() failure (HRESULT 0x8007010b)

要运行图像,我键入以下命令:

docker run -p 1433:1433 myimage

或偶数

docker run myimage

,并且两个时尚都会产生相同的错误。

当我输入:

docker images

我可以看到:

REPOSITORY                 TAG             IMAGE ID           CREATED           SIZE
myimage                    latest          ffc13a86b57b       28 seconds ago    2.83GB

哪个确认图像是正确创建的。

最终编辑

我认为我将共享由此产生的dockerfile和最终解决方案。

目标

目标是将客户端的数据库MDF和LDF文件列入SQL Server中,然后将它们安装在Docker容器中,以避免安装我不在我不在的本地SQL Server实例的过程确实需要。

从@Alwayslearning状态进行的课程

复制指令是通过root root 用户处理的,因此采取对/var/opt/mssql的所有权。完全按照她/他说的解决了问题。因此,如 @ewansinglearning的答案中所述,需要将文件夹的所有权回到mssql用户。大笔!

最终解决方案

最终解决方案是能够将客户端的数据库文件安装/附加到SQL Server的容器实例。为此,我需要编写一个可以做到这一点的Shell脚本。

attact-db.sh

sleep 15s

/opt/mssql-tools/bin/sqlcmd -S . -U sa -P $tr0ngP@ssw0rd! -Q "CREATE DATABASE [mydb] ON (FILENAME = '/var/opt/mssql/data/mydb.mdf'),(FILENAME = '/var/opt/mssql/data/mydb_log.ldf') FOR ATTACH"

这来自这里:通过dockerfile

dockerfile

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=$tr0ngP@ssw0rd!

COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
COPY attach-db.sh /var/opt/mssql/data/attach-db.sh

ENTRYPOINT /var/opt/mssql/data/attach-db.sh & /opt/mssql/bin/sqlservr

运行构建图像

docker run -p 1433:1433 --hostname mydb myimage

连接到数据库

下载并安装Azure Data Stutio 需要连接到容器化的SQL Server实例。

Trying to mount a db into a mssql docker container

Dockerfile

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP@ssw0rd!
ENV MSSQL_TCP_PORT=1433
EXPOSE 1433

COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf

ENTRYPOINT /opt/mssql/bin/sqlservr

EDIT

It seems that the only thing that prevents the image from running as a container is when I add those two COPY instructions within the Dockerfile. Everything works fine when I remove the two COPY.

In fact, it says that it can't copy c:\tempdata\master.mdf to /var/opt/mssql/data/master.mdf. But why is that?

Lately, when

Structure

All files are in the same folder on my local machine.

myfolder
    /Dockerfile
    /mydb.mdf
    /mydb_log.ldf 

Environment

  • Windows 10 for Workstation

  • Docker Desktop 4.5.1 (74721) (

    Engine 20.10.12,

    Compose 1.29.2,

    Kubernetes 1.22.5,

    Snyk 1.827.0,

    Credential Helper 0.6.4)

  • Visual Studio Code 1.67.2

Error obtained

The image is built in a flawless fashion, letting believe everything's fine. But when I run it, I get an error:

ERROR: BootstrapSystemDataDirectories() failure (HRESULT 0x8007010b)

To run the image, I type the following command:

docker run -p 1433:1433 myimage

or even

docker run myimage

and both fashions creates the same error.

When I type in:

docker images

I can see:

REPOSITORY                 TAG             IMAGE ID           CREATED           SIZE
myimage                    latest          ffc13a86b57b       28 seconds ago    2.83GB

Which confirms that the image is correctly created.

FINAL EDIT

I thought I would share the resulting Dockerfile and final solution.

The Goal

The goal was to take a client's database MDF and LDF files in SQL Server and mount them in a Docker Container to avoid the process of installing a local SQL Server instance which I don't really need.

Lesson LEARNED

As @AlwaysLearning states, the COPY instructions are processed through the root user of the container, hence taking ownership over the /var/opt/mssql. Doing exactly as she/he said solved the problem. So folder's ownership needs to be given back to mssql user as described in @AlwaysLearning's answer. BIG THX!

Final Solution

The final solution is to be able to mount/attach the client's database files to the containerized instance of SQL Server. For that to work, I needed to write a shell script which does just that.

attach-db.sh

sleep 15s

/opt/mssql-tools/bin/sqlcmd -S . -U sa -P $tr0ngP@ssw0rd! -Q "CREATE DATABASE [mydb] ON (FILENAME = '/var/opt/mssql/data/mydb.mdf'),(FILENAME = '/var/opt/mssql/data/mydb_log.ldf') FOR ATTACH"

This comes from here: Attaching databases via a dockerfile

Dockerfile

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=$tr0ngP@ssw0rd!

COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
COPY attach-db.sh /var/opt/mssql/data/attach-db.sh

ENTRYPOINT /var/opt/mssql/data/attach-db.sh & /opt/mssql/bin/sqlservr

Running the built image

docker run -p 1433:1433 --hostname mydb myimage

Connecting to database

Download and install Azure Data Studio is required to connect to a containerized SQL Server instance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥抱没勇气 2025-02-12 17:33:23

如果检查Docker容器的日志,您会看到完整的错误消息是:

2022-06-09 00:12:57.28 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2022-06-09 00:12:57.33 Server      ERROR: Setup FAILED copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf':  5(Access is denied.)
ERROR: BootstrapSystemDataDirectories() failure (HRESULT 0x80070005)

这是因为Dockerfile 复制操作是作为root用户执行的root用户拥有的文件系统对象如下所示:

$ ls -la /var/opt/mssql/data
total 12
drwxr-xr-x 1 root root 4096 Jun  9 00:12 .
drwxrwx--- 1 root root 4096 Jun  9 00:12 ..
-rw-r--r-- 1 root root    0 Jun  9 00:06 mydb.mdf
-rw-r--r-- 1 root root    0 Jun  9 00:06 mydb_log.ldf

SQL Server服务本身是使用MSSQL用户执行的,因此现在它无法访问> /var/opt/mssql/data目录添加自己的文件。您可以通过将文件和目录的所有权更改为MSSQL用户,即:

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP@ssw0rd!

COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf

USER root
RUN chown -R mssql:root /var/opt/mssql
USER mssql

现在容器将成功启动,您可以看到SQL Server服务能够复制其Bootstrap文件在/var/opt/mssql/data目录中:

$ ls -la /var/opt/mssql/data
total 81168
drwxr-xr-x 1 mssql root     4096 Jun  9 00:23 .
drwxrwx--- 1 mssql root     4096 Jun  9 00:23 ..
-rw-r----- 1 mssql root      256 Jun  9 00:23 Entropy.bin
-rw-r----- 1 mssql root  4653056 Jun  9 00:23 master.mdf
-rw-r----- 1 mssql root  2097152 Jun  9 00:23 mastlog.ldf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 model.mdf
-rw-r----- 1 mssql root 14090240 Jun  9 00:23 model_msdbdata.mdf
-rw-r----- 1 mssql root   524288 Jun  9 00:23 model_msdblog.ldf
-rw-r----- 1 mssql root   524288 Jun  9 00:23 model_replicatedmaster.ldf
-rw-r----- 1 mssql root  4653056 Jun  9 00:23 model_replicatedmaster.mdf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 modellog.ldf
-rw-r----- 1 mssql root 14090240 Jun  9 00:23 msdbdata.mdf
-rw-r----- 1 mssql root   524288 Jun  9 00:23 msdblog.ldf
-rw-r--r-- 1 mssql root        0 Jun  9 00:06 mydb.mdf
-rw-r--r-- 1 mssql root        0 Jun  9 00:06 mydb_log.ldf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 tempdb.mdf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 tempdb2.ndf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 templog.ldf

编辑:

值得指出的是,dockerfile 复制命令还可以设置所有者+group将文件复制到图像时,属性会在fly上进行。然后,这减轻了切换到用户根的需求,然后返回用户mssql,以便应用chown,即:

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP@ssw0rd!

COPY --chown=mssql:root mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY --chown=mssql:root mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf

If you check the logs for the Docker container you'll see that the complete error message is:

2022-06-09 00:12:57.28 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2022-06-09 00:12:57.33 Server      ERROR: Setup FAILED copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf':  5(Access is denied.)
ERROR: BootstrapSystemDataDirectories() failure (HRESULT 0x80070005)

This happens because the Dockerfile COPY actions are performed as the root user which leave the file system objects owned by the root user as seen with:

$ ls -la /var/opt/mssql/data
total 12
drwxr-xr-x 1 root root 4096 Jun  9 00:12 .
drwxrwx--- 1 root root 4096 Jun  9 00:12 ..
-rw-r--r-- 1 root root    0 Jun  9 00:06 mydb.mdf
-rw-r--r-- 1 root root    0 Jun  9 00:06 mydb_log.ldf

The SQL Server service itself is executed using the mssql user so now it doesn't have access to the /var/opt/mssql/data directory to add its own files. You can correct that situation by changing the ownership of the files and directories to the mssql user, i.e.:

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP@ssw0rd!

COPY mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf

USER root
RUN chown -R mssql:root /var/opt/mssql
USER mssql

Now the container will start successfully and you can see that the SQL Server service was able to copy its bootstrap files into the /var/opt/mssql/data directory:

$ ls -la /var/opt/mssql/data
total 81168
drwxr-xr-x 1 mssql root     4096 Jun  9 00:23 .
drwxrwx--- 1 mssql root     4096 Jun  9 00:23 ..
-rw-r----- 1 mssql root      256 Jun  9 00:23 Entropy.bin
-rw-r----- 1 mssql root  4653056 Jun  9 00:23 master.mdf
-rw-r----- 1 mssql root  2097152 Jun  9 00:23 mastlog.ldf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 model.mdf
-rw-r----- 1 mssql root 14090240 Jun  9 00:23 model_msdbdata.mdf
-rw-r----- 1 mssql root   524288 Jun  9 00:23 model_msdblog.ldf
-rw-r----- 1 mssql root   524288 Jun  9 00:23 model_replicatedmaster.ldf
-rw-r----- 1 mssql root  4653056 Jun  9 00:23 model_replicatedmaster.mdf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 modellog.ldf
-rw-r----- 1 mssql root 14090240 Jun  9 00:23 msdbdata.mdf
-rw-r----- 1 mssql root   524288 Jun  9 00:23 msdblog.ldf
-rw-r--r-- 1 mssql root        0 Jun  9 00:06 mydb.mdf
-rw-r--r-- 1 mssql root        0 Jun  9 00:06 mydb_log.ldf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 tempdb.mdf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 tempdb2.ndf
-rw-r----- 1 mssql root  8388608 Jun  9 00:23 templog.ldf

Edit:

It's worth pointing out that the Dockerfile COPY command can also set owner+group attributes on-the-fly whilst copying files into the image. This then alleviates the need to switch to USER root and back to USER mssql so as to apply chown manually, i.e.:

FROM mcr.microsoft.com/mssql/server:2019-latest
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Str0ngP@ssw0rd!

COPY --chown=mssql:root mydb.mdf /var/opt/mssql/data/mydb.mdf
COPY --chown=mssql:root mydb_log.ldf /var/opt/mssql/data/mydb_log.ldf
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文