来自 Dockerfile 运行 步骤的数据不在图像中

Data from Dockerfile RUN step not in image

我正在为 运行 软件集成测试设置一个 MongoDB 容器,我想让 docker 文件将测试用户添加到数据库中,以便测试可以登录并执行他们的步骤。我希望能够捕获 Dockerfile 中的所有步骤,因此我试图避免启动容器、手动添加用户,然后重新捕获图像。

为此,我创建了这个 Dockerfile:

FROM mongo:3.2.0
COPY add_user.sh /
RUN /add_user.sh

add_user.sh包含:

#!/bin/bash
mongod &

RET=1
while [[ RET -ne 0 ]]; do
    sleep 1
    mongo admin --eval "help" >/dev/null 2>&1
    RET=$?
done

echo "Adding testUser..."
mongo admin --eval "db.createUser({user:'testUser',pwd:'P@ssw0rd',roles:['readWrite']})"

echo "User added"
mongo admin --eval "db.getUsers()"

mongod --shutdown

在构建镜像时,我可以看到用户已成功添加,但是当我运行镜像时,容器中的数据库不包含任何用户。

为什么图像中没有捕捉到用户?如何在映像构建过程中添加用户?

原因是mongo图像使用VOLUME作为数据目录,这使得docker将数据库数据存储在外部图像的一部分,并且该数据不会保留在图像中(请参阅 mongo:3.2 图像的 Dockerfile;https://github.com/docker-library/mongo/blob/fcb9584617e63f1d3db8dc730fb8abb83653c7ad/3.2/Dockerfile#L54

因此,即使命令 运行 成功,数据库本身也存储在图像之外。

在 docker 中,使用了卷,因此数据的持久化独立于容器的生命周期(即,您可以销毁容器,但卷内的数据会保留下来,这样您就可以开始一个新容器,使用相同的 volume/data)

缺点是,如果 Dockerfile 使用 VOLUME 声明,则无法 "bake" 图像中的数据。

有关此问题的一些讨论,请参阅 https://github.com/docker/docker/issues/18287, and https://github.com/docker/docker/issues/3465