尝试使用MongoDB数据库创建Docker映像,但是即使成功加载容器也没有该映像

时间:2019-03-04 19:04:02

标签: mongodb docker

数据库中的数据旨在通过另一个容器中的API进行显示。以前,我已经在使用this suggestion的运行过程中成功加载了数据库。但是,我的数据库很大(10gb),理想情况下,每次启动新容器时都不必再次加载数据库。我希望数据库在构建时加载。为此,我对Dockerfile尝试了以下操作:

FROM mongo:4.0.6-xenial

COPY dump /data/dump

RUN mongod --fork --logpath /var/log/mongod.log \
&& mongorestore /data/dump \
&& mongo --eval "db.getSiblingDB('db').createUser({user:'user',pwd:'pwd',roles:['readWrite']})" \
&& mongod --shutdown

运行该映像时,我希望数据库位于容器中,但实际上不是,用户也不存在。但是,据我所知,日志文件/var/log/mongod.log指示数据库已成功加载。为什么这不起作用?

1 个答案:

答案 0 :(得分:1)

official mongo Docker image将数据库数据写入docker volume

在运行时(因此在docker容器中),请记住,写入卷的文件最终不会写入容器文件系统中。这样做是为了持久保存数据,以使其在容器删除后仍然存在,但出于性能原因,更重要的是在数据库环境中。为了使磁盘具有良好的I / O性能,磁盘操作必须在卷上完成,而不是在容器文件系统本身上完成。

在构建时(因此在创建Docker映像时),如果您碰巧在Dockerfile中有RUN / ADD / COPY指令将文件写入到已声明的位置作为一个卷,这些文件将被丢弃。但是,如果将文件写入Dockerfile中的目录,并且仅在将该目录声明为卷之后,这些卷将保留这些文件,除非您使用docker run -v选项启动容器来指定卷。

这意味着在构建FROM mongo您自己的Dockerfile的情况下,/data位置已被声明为卷。将文件写入该位置毫无意义。

该怎么办?

让您从头开始拥有mongo图片

了解卷的工作原理后,您可以从官方mongo Docker映像的Dockerfile复制内容,并插入RUN / ADD / COPY指令以编写您想要的文件/data/db指令之前的位置。

覆盖入口点

假设您有一个名为VOLUME /data/db /data/configdb的tar存档,其中包含来自您想要的所有数据库和集合的mongo容器中mongo-data-db.tar位置的内容,则可以使用以下 Dockerfile copy-initial-data-entry-point.sh ,您可以构建一个映像,该映像将在每次启动容器时将这些数据复制到/data/db位置。 这仅在以下情况下才有意义:将这样的容器用于测试套件,该套件每次启动时都需要非常相同的初始数据,因为每次启动时都将初始数据替换为初始数据。

Dockerfile:

/data/db

copy-initial-data-entry-point.sh:

FROM mongo
COPY ./mongo-data-db.tar /mongo-data-db.tar
COPY ./copy-initial-data-entry-point.sh /
RUN chmod +x /copy-initial-data-entry-point.sh
ENTRYPOINT [ "/copy-initial-data-entry-point.sh"]
CMD ["mongod"]

要从名为#!/bin/bash set -e tar xf /mongo-data-db.tar -C / exec /usr/local/bin/docker-entrypoint.sh "$@" 的mongo容器中提取/data/db的内容,请执行以下操作:

  • 停止mongo容器:my-mongo-container
  • 创建一个临时容器,以从以下卷中生成tar归档文件:docker stop my-mongo-container

请注意,此归档文件将非常大,因为它包含mongo服务器数据的完整内容,包括mongo documentation

中所述的索引