为什么Docker Mongo在图像构建期间拒绝连接

时间:2017-09-01 13:55:00

标签: mongodb docker

我正在尝试使用已包含某些数据的正在运行的mongodb实例制作Docker镜像。所以我就像这样Dockerfile

FROM mongo:3.4    
RUN mongo --eval "printjson(db.serverStatus())"

我立刻得到了这个错误:

Sending build context to Docker daemon  7.168kB
Step 1/3 : FROM mongo:3.4
---> b39de1d79a53
Step 2/3 : RUN mongo --eval "printjson(db.serverStatus())"
---> Running in 778f00a25623
MongoDB shell version v3.4.7
connecting to: mongodb://127.0.0.1:27017
2017-09-01T13:42:23.128+0000 W NETWORK  [thread1] Failed to connect to 127.0.0.1:27017, in(checking socket for error after poll), reason: Connection refused
2017-09-01T13:42:23.128+0000 E QUERY    [thread1] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed :
connect@src/mongo/shell/mongo.js:237:13
@(connect):1:6
exception: connect failed
The command '/bin/sh -c mongo --eval "printjson(db.serverStatus())"' returned a non-zero code: 1

也就是说,mongod守护进程拒绝了我的连接。

为什么他会做这样的事情?特别是当我可以从外面自由连接到数据库时。

编辑:

我试着用mongod =>替换RUN命令来查看service mongod status服务是否正在运行mongod:unrecognized service。所以似乎mongod服务不是runnig。这是奇怪的,因为我导出的mongo:3.4图像的last statement以:

结束
CMD ["mongod"]

2 个答案:

答案 0 :(得分:4)

您正在构建Docker镜像,在构建阶段,mongo服务根本没有运行。

构建docker镜像只是按顺序执行命令列表。没有守护进程监听,因此您的命令无法正常工作。

您可能需要run您的图片并在正在运行的container上执行命令,例如:

docker run -d --name=my-name mongo:3.4
docker exec -ti my-name mongo --eval "printjson(db.serverStatus())"

使用这2个命令,首先执行mongo容器(通过实例化mongo:3.4图像),然后在运行容器中执行命令。

答案 1 :(得分:1)

首先,在构建图像时,图像中没有任何内容正在运行。进程仅在运行映像时运行。

FROM mongo:3.4    
RUN mongo --eval "printjson(db.serverStatus())"

每个RUN语句都在一个没有运行其他任何东西的新shell中执行。所以如果你需要运行一些东西来检查,你需要自己运行它,它只能用于当前的语句

RUN mongod & ; echo "Waiting for mongo to be up"; sleep 20; mongo --eval "printjson(db.serverStatus())"; pkill mongod

这将只为RUN步骤启动mongo,如果你在它之后添加另一个语句

RUN mongo --eval "printjson(db.serverStatus())"

那不行。新shell,没有来自旧运行语句的进程。当前目录重置为WORKDIR

的任何内容

您只能在运行图像时执行命令。所以你会使用类似下面的东西

docker run --name mongoserver -d mongo:3.4
docker exec mongoserver mongo --eval "printjson(db.serverStatus())"

第一个命令在后台启动图像,下一个命令运行另一个过程。如果这个过程需要时间起床,你可能需要在两者之间休息一下