mongodb 如何使用默认集合和数据创建 Mongo Docker 映像?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33558506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:34:10  来源:igfitidea点击:

How to create a Mongo Docker Image with default collections and data?

mongodbdockerdockerfile

提问by Felipe Plets

I need support here to build my own mongo docker image.

我需要这里的支持来构建我自己的 mongo docker 镜像。

I have a list of scripts to create and insert data into the MongoDB that shall be called in my Dockerfile to deliver a docker image with default collections and data.

我有一个脚本列表,用于创建数据并将数据插入到 MongoDB 中,这些脚本将在我的 Dockerfile 中调用以提供具有默认集合和数据的 docker 映像。

Here is how my Dockerfile looks like currently:

这是我的 Dockerfile 目前的样子:

FROM mongo:latest

RUN mkdir -p /data/scripts

COPY . /data/scripts

RUN mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db/

RUN FILES=scripts/*-create.js
RUN for f in $FILES; do mongo mydb $f; done

RUN FILES=scripts/*-insert.js
RUN for f in $FILES; do mongo mydb $f; done

RUN mongod --shutdown

I've tried different options to start and stop mongod and always one of the two fail, the current script raise the following error:

我尝试了不同的选项来启动和停止 mongod 并且总是两者之一失败,当前脚本引发以下错误:

There doesn't seem to be a server running with dbpath: /data/db

Update

更新

After @Matt answer I could run successfully the command chain, but can't still see my database (called my-db), collections and data there.

在@Matt 回答后,我可以成功运行命令链,但仍然无法在那里看到我的数据库(称为 my-db)、集合和数据。

The current Dockerfile:

当前的 Dockerfile:

FROM mongo:latest

RUN mkdir -p /data/db/scripts

COPY . /data/db

RUN mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db \
    && CREATE_FILES=/data/db/scripts/*-create.js \
    && for f in $CREATE_FILES; do mongo 127.0.0.1:27017 $f; done \
    && INSERT_FILES=/data/db/scripts/*-insert.js \
    && for f in $INSERT_FILES; do mongo 127.0.0.1:27017 $f; done \
    && mongod --shutdown 

The output from the docker build command:

docker build 命令的输出:

Sending build context to Docker daemon 10.24 kB
Step 1 : FROM mongo:latest
 ---> c08c92f4cb13
Step 2 : RUN mkdir -p /data/db/scripts
 ---> Running in a7088943bb57
 ---> 373c7319927d
Removing intermediate container a7088943bb57
Step 3 : COPY . /data/db
 ---> 8fa84884edb7
Removing intermediate container ae43e2c24fee
Step 4 : RUN mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db     && CREATE_FILES=/data/db/scripts/*-create.js    && for f in $CREATE_FILES; do mongo 127.0.0.1:27017 $f; done    && INSERT_FILES=/data/db/scripts/*-insert.js    && for f in $INSERT_FILES; do mongo 127.0.0.1:27017 $f; done    && mongod --shutdown
 ---> Running in 33970b6865ee
about to fork child process, waiting until server is ready for connections.
forked process: 10
child process started successfully, parent exiting
MongoDB shell version: 3.0.7
connecting to: 127.0.0.1:27017/test
MongoDB shell version: 3.0.7
connecting to: 127.0.0.1:27017/test
killing process with pid: 10
 ---> 8451e43b7749
Removing intermediate container 33970b6865ee
Successfully built 8451e43b7749

But as I said, I still can't see the database, collections and data in my database using mongo shell. Also I connected to the running container and got the mongodb.log:

但是正如我所说,我仍然无法使用mongo shell查看数据库中的数据库,集合和数据。我还连接到正在运行的容器并获得了 mongodb.log:

2015-11-06T16:15:14.562+0000 I JOURNAL  [initandlisten] journal dir=/data/db/journal
2015-11-06T16:15:14.562+0000 I JOURNAL  [initandlisten] recover : no journal files present, no recovery needed
2015-11-06T16:15:14.698+0000 I JOURNAL  [initandlisten] preallocateIsFaster=true 2.36
2015-11-06T16:15:14.746+0000 I JOURNAL  [durability] Durability thread started
2015-11-06T16:15:14.746+0000 I JOURNAL  [journal writer] Journal writer thread started
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] MongoDB starting : pid=10 port=27017 dbpath=/data/db 64-bit host=9c05d483673a
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] 
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] 
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] 
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] 
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] db version v3.0.7
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] git version: 6ce7cbe8c6b899552dadd907604559806aa2e9bd
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] build info: Linux ip-10-183-78-195 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 BOOST_LIB_VERSION=1_49
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] allocator: tcmalloc
2015-11-06T16:15:14.747+0000 I CONTROL  [initandlisten] options: { processManagement: { fork: true }, storage: { dbPath: "/data/db" }, systemLog: { destination: "file", path: "/var/log/mongodb.log" } }
2015-11-06T16:15:14.748+0000 I INDEX    [initandlisten] allocating new ns file /data/db/local.ns, filling with zeroes...
2015-11-06T16:15:14.802+0000 I STORAGE  [FileAllocator] allocating new datafile /data/db/local.0, filling with zeroes...
2015-11-06T16:15:14.802+0000 I STORAGE  [FileAllocator] creating directory /data/db/_tmp
2015-11-06T16:15:14.804+0000 I STORAGE  [FileAllocator] done allocating datafile /data/db/local.0, size: 64MB,  took 0 secs
2015-11-06T16:15:14.807+0000 I NETWORK  [initandlisten] waiting for connections on port 27017
2015-11-06T16:15:14.830+0000 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:49641 #1 (1 connection now open)
2015-11-06T16:15:14.832+0000 I INDEX    [conn1] allocating new ns file /data/db/my-db.ns, filling with zeroes...
2015-11-06T16:15:14.897+0000 I STORAGE  [FileAllocator] allocating new datafile /data/db/my-db.0, filling with zeroes...
2015-11-06T16:15:14.898+0000 I STORAGE  [FileAllocator] done allocating datafile /data/db/my-db.0, size: 64MB,  took 0 secs
2015-11-06T16:15:14.904+0000 I NETWORK  [conn1] end connection 127.0.0.1:49641 (0 connections now open)
2015-11-06T16:15:14.945+0000 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:49642 #2 (1 connection now open)
2015-11-06T16:15:14.958+0000 I NETWORK  [conn2] end connection 127.0.0.1:49642 (0 connections now open)
2015-11-06T16:15:14.982+0000 I CONTROL  [signalProcessingThread] got signal 15 (Terminated), will terminate after current cmd ends
2015-11-06T16:15:14.982+0000 I CONTROL  [signalProcessingThread] now exiting
2015-11-06T16:15:14.982+0000 I NETWORK  [signalProcessingThread] shutdown: going to close listening sockets...
2015-11-06T16:15:14.982+0000 I NETWORK  [signalProcessingThread] closing listening socket: 6
2015-11-06T16:15:14.982+0000 I NETWORK  [signalProcessingThread] closing listening socket: 7
2015-11-06T16:15:14.982+0000 I NETWORK  [signalProcessingThread] removing socket file: /tmp/mongodb-27017.sock
2015-11-06T16:15:14.982+0000 I NETWORK  [signalProcessingThread] shutdown: going to flush diaglog...
2015-11-06T16:15:14.982+0000 I NETWORK  [signalProcessingThread] shutdown: going to close sockets...
2015-11-06T16:15:14.982+0000 I STORAGE  [signalProcessingThread] shutdown: waiting for fs preallocator...
2015-11-06T16:15:14.982+0000 I STORAGE  [signalProcessingThread] shutdown: final commit...
2015-11-06T16:15:15.008+0000 I JOURNAL  [signalProcessingThread] journalCleanup...
2015-11-06T16:15:15.008+0000 I JOURNAL  [signalProcessingThread] removeJournalFiles
2015-11-06T16:15:15.009+0000 I JOURNAL  [signalProcessingThread] Terminating durability thread ...
2015-11-06T16:15:15.088+0000 I JOURNAL  [journal writer] Journal writer thread stopped
2015-11-06T16:15:15.088+0000 I JOURNAL  [durability] Durability thread stopped
2015-11-06T16:15:15.088+0000 I STORAGE  [signalProcessingThread] shutdown: closing all files...
2015-11-06T16:15:15.090+0000 I STORAGE  [signalProcessingThread] closeAllFiles() finished
2015-11-06T16:15:15.090+0000 I STORAGE  [signalProcessingThread] shutdown: removing fs lock...
2015-11-06T16:15:15.090+0000 I CONTROL  [signalProcessingThread] dbexit:  rc: 0

I also checked the folder /data/db content:

我还检查了文件夹 /data/db 内容:

root@fbaf17233182:/data/db# ls -al
total 16
drwxr-xr-x 3 mongodb mongodb 4096 Nov  6 16:15 .
drwxr-xr-x 4 root    root    4096 Nov  6 16:15 ..
drwxr-xr-x 2 root    root    4096 Nov  5 18:55 scripts

May help:

可能有帮助:

采纳答案by Felipe Plets

The problem was that information could not be saved on /db/data, so I've created a solution creating my own data directory.

问题是信息无法保存在 上/db/data,所以我创建了一个解决方案来创建我自己的数据目录。

# Parent Dockerfile https://github.com/docker-library/mongo/blob/982328582c74dd2f0a9c8c77b84006f291f974c3/3.0/Dockerfile
FROM mongo:latest

# Modify child mongo to use /data/db2 as dbpath (because /data/db wont persist the build)
RUN mkdir -p /data/db2 \
    && echo "dbpath = /data/db2" > /etc/mongodb.conf \
    && chown -R mongodb:mongodb /data/db2

COPY . /data/db2

RUN mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db2 --smallfiles \
    && CREATE_FILES=/data/db2/scripts/*-create.js \
    && for f in $CREATE_FILES; do mongo 127.0.0.1:27017 $f; done \
    && INSERT_FILES=/data/db2/scripts/*-insert.js \
    && for f in $INSERT_FILES; do mongo 127.0.0.1:27017 $f; done \
    && mongod --dbpath /data/db2 --shutdown \
    && chown -R mongodb /data/db2

# Make the new dir a VOLUME to persists it 
VOLUME /data/db2

CMD ["mongod", "--config", "/etc/mongodb.conf", "--smallfiles"]

Thanks to @yosifkit from the docker-library/mongoGithub project for pointing that the volume would store the data in the resulting image. I missed that on the documentation.

感谢来自 docker -library/mongoGithub 项目的@yosifkit指出该卷会将数据存储在结果图像中。我在文档中错过了这一点。

回答by Matt

During a docker image build, each build command like RUNis launched in it's own docker container and then when the command completes the data is committed as an image. If you run dockviz images --treewhile doing a build you will get the idea.

在 docker 镜像构建期间,每个构建命令RUN都在它自己的 docker 容器中启动,然后当命令完成时,数据作为镜像提交。如果您dockviz images --tree在进行构建时运行,您就会明白这一点。

In your case mongodhas started and stopped long before you need it. You need to start mongo and run your scripts all in the one RUNstep. You can achieve that by using a shell script that launches mongod and inserts your data.

在你的情况下mongod,在你需要它之​​前很久就已经开始和停止了。您需要RUN一步启动 mongo 并运行您的脚本。您可以通过使用启动 mongod 并插入数据的 shell 脚本来实现这一点。

Your Dockerfilewill run:

Dockerfile将运行:

RUN mongo_create_insert.sh

Then mongo_create_insert.shcontains all your mongo dependent steps:

然后mongo_create_insert.sh包含您所有的 mongo 依赖步骤:

#!/usr/bin/env bash

mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db/

FILES=scripts/*-create.js
for f in $FILES; do mongo mydb $f; done

FILES=scripts/*-insert.js
for f in $FILES; do mongo mydb $f; done

mongod --shutdown

As a side note, I tend to install Ansible in my base image and use that to provision Docker images in single RUNcommand rather than doing lots of shell RUN steps in a Dockerfile (which is just a glorified shell script in the end). You lose some of the build caching niceness but we've moved on from provisioning with shell scripts for a reason.

附带说明一下,我倾向于在我的基础映像中安装 Ansible,并使用它在单个RUN命令中配置 Docker 映像,而不是在 Dockerfile(最终只是一个美化的 shell 脚本)中执行大量 shell RUN 步骤。您失去了一些构建缓存的优点,但出于某种原因,我们已经不再使用 shell 脚本进行配置。

回答by Siyu

According to the description of the image on DockerHub, there is a much cleaner and simpler solution for this.

根据 DockerHub 上镜像的描述,对此有一个更清晰、更简单的解决方案。

When a container is started for the first time it will execute files with extensions .sh and .js that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. .js files will be executed by mongo using the database specified by the MONGO_INITDB_DATABASE variable, if it is present, or test otherwise. You may also switch databases within the .js script.

当容器第一次启动时,它将执行扩展名为 .sh 和 .js 的文件,这些文件位于 /docker-entrypoint-initdb.d 中。文件将按字母顺序执行。.js 文件将由 mongo 使用 MONGO_INITDB_DATABASE 变量指定的数据库(如果存在)执行,否则进行测试。您还可以在 .js 脚本中切换数据库。

First, the Dockerfile is as simple as

首先,Dockerfile 很简单

FROM mongo:4
COPY setup.sh /docker-entrypoint-initdb.d/
COPY scripts /

Then, in the setup.sh, add your user/collection creation script, for example

然后,在 中setup.sh,添加您的用户/集合创建脚本,例如

mongo=( mongo --host 127.0.0.1 --port 27017 --quiet )
mongo+=(
    --username="$MONGO_INITDB_ROOT_USERNAME"
    --password="$MONGO_INITDB_ROOT_PASSWORD"
    --authenticationDatabase="$rootAuthDatabase"
)

CREATE_FILES=/scripts/*-create.js 
for f in $CREATE_FILES; do "${mongo[@]}" "$MONGO_INITDB_DATABASE" $f; done 

INSERT_FILES=/scripts/*-insert.js 
for f in $INSERT_FILES; do "${mongo[@]}" "$MONGO_INITDB_DATABASE" $f; done