数据库中的数据旨在通过另一个容器中的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指示数据库已成功加载。为什么这不起作用?
答案 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 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
的内容,请执行以下操作:
my-mongo-container
docker stop my-mongo-container
请注意,此归档文件将非常大,因为它包含mongo服务器数据的完整内容,包括mongo documentation
中所述的索引