Dachstein
Dachstein

Reputation: 4282

Why does Docker Mongo refuse connection during image build

I am trying to make a Docker image with a running mongodb instance that would already contain some data. So I make my Dockerfile like this:

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

And I immediately get this error:

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

That is, the mongod daemon refused my connection.

Why would he do such a thing? Especially when I can freely connect to the database from the outside.

EDIT:

I tried to see if the mongod service is running at all by replacing the RUN command with service mongod status => mongod:unrecognized service. So it seems that the mongod service is not runnig. Which is odd, since the last statement of the mongo:3.4 image from which I am deriving ends with:

CMD ["mongod"]

Upvotes: 2

Views: 656

Answers (2)

Tarun Lalwani
Tarun Lalwani

Reputation: 146620

First of all when you are building image, there is nothing that is running in your image. Processes only run when run the image.

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

Every RUN statement is executed in a new shell where nothing else is running. So if you need to run something to check, you need to run it yourself and it will only be available for the current statement

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

And that will launch mongo for just that RUN step and if you add another statement just after it

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

That won't work. New shell, no processes from old run statement. Current directory reset to whatever the WORKDIR is

You can only execute commands when running the image. So you would use something like below

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

The first command launches the image in background and the next on runs an additional process. You may need some sleep between the two if the process takes time to get up

Upvotes: 2

whites11
whites11

Reputation: 13300

You are building a Docker image, the mongo service is not running at all during build phase.

Building a docker image is just executing a list of commands in sequence. There is no daemon listening, so your command cannot work.

You may want to run your image and execute your commands on a running container, for example:

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

With this 2 commands, you first execute a mongo container (by instantianting the mongo:3.4 image) and then you excecute a command in the running container.

Upvotes: 4

Related Questions