Why does Docker Mongo refuse connection during image build - mongodb

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"]

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.

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

Related

Connect to MongoDB query router for Sharding on a docker container running on windows10

This is a follow up of my previous question. Alex Blex's solution for connecting to the config servers works great. But I am facing the same issue while connecting to the MongoDB Query router.
Below is the command I am using to create the mongos server
docker run -d -p 40001:27017 -v C:/mongodata/data/db --name QR mongo mongos --configdb rs1/172.30.35.165:30001,172.30.32.73:30002,172.30.42.189:30003 --bind_ip 0.0.0.0 --port 27017
But I get the below error on executing docker exec -it QR mongo -port 27017:-
connecting to:
mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Error: couldn't connect to server 127.0.0.1:27017, connection attempt
failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused
by :: No connection could be ma de because the target machine actively
refused it. : connect#src/mongo/shell/mongo.js:374:17 #(connect):2:6
exception: connect failed exiting with code 1
Below is the replication configuration details for the Config Servers -
config = {
"_id": "rs1",
"configsvr": true,
"members":
[
{
"_id": 0,
"host": "6ed1d953f979:27019"
},
{
"_id": 1,
"host": "086f0ef5c955:27019"
},
{
"_id": 2,
"host": "391c9c07b341:27019"
}
]
}
Here is the container ID and IP address
------------------------------------------
Server IP Address Container ID
------------------------------------------
asiaCS 172.30.35.165 6ed1d953f979
europeCS 172.30.32.73 086f0ef5c955
americaCS 172.30.42.189 391c9c07b341
I am not sure if I am even configuring the mongos properly.
So I figured this one out. Apparently config servers are light weight and do not store any data. Hence, we do not require to bind it to a volume. I first bound all the config servers to a fixed IP (so that docker doesn't assign them a new IP every time I stop and start a container). But for the sake of this answer, I will be using the IPs mentioned in the question itself. I used the below command to create a query router.
docker run -d -p 40001:27017 --name QR --hostname QR mongo mongos --configdb "rs1/172.30.35.165:30001,172.30.32.73:30002,172.30.42.189:30003" --bind_ip 0.0.0.0
Then docker exec'd into the container by running docker exec -it QR mongo
Now while connecting to mongos, if it throws a connection refused error (the one mentioned in the question), you could use the following command -
docker exec -it QR mongos --configdb "rs1/172.30.35.165:30001,172.30.32.73:30002,172.30.42.189:30003"
The above command will start the mongos without the detached mode and logs will start appearing on your CMD or PowerShell (whichever way you are running the command) console.
I have mongo shell on my local and I opened another CMD prompt and executed the below command -
C:\MongoShell\bin> mongosh --host IpAddressOfMongos --port 27017
And voila, it connected successfully. You can then close the initial console where you were running docker exec command in attached mode.
IP Address of the mongos can be found out by doing docker inspect QR.

couldn't connect to server 127.0.0.1:27017 when trying to run mongo command using docker

I'm trying to run a mongo script on a docker container using this command
docker run --rm -it --volume "$(pwd):/scripts" mongo:latest mongo /scripts/${SCRIPT_FILE_NAME}, and I'm keeping getting this error:
MongoDB shell version v4.4.0
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect#src/mongo/shell/mongo.js:362:17
#(connect):2:6
exception: connect failed
exiting with code 1
The docker run command that you shared attempts to execute explicitly the mongo /scripts/${SCRIPT_FILE_NAME} command, immediately when the container is started.
At that point in time, the mongodb daemon isn't ready to accept connections(yet).
Instead of trying to initialize manually, you should leverage the built-in mongo mechanism that discovers the scripts under /docker-entrypoint-initdb.d and executes them when the DB is running.
When a mongo 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.
Check the mongo image official documentation for more details.

Unable to open Mongo shell using Docker run but exec

What I want to is open mongo shell in terminal.
When I run mongo container using run with mongo command,
I got an error.
$ docker run -it --name mongodb mongo:latest mongo
MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
2019-12-01T10:01:18.524+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect#src/mongo/shell/mongo.js:341:17
#(connect):2:6
2019-12-01T10:01:18.526+0000 F - [main] exception: connect failed
2019-12-01T10:01:18.526+0000 E - [main] exiting with code 1
But when I run mongo first and exec command later, I can open mongo shell nicely.
$ docker run -d --name mongodb mongo:latest
0296856a6e614667ad7cb81cac104d2704369d8d98f9c5dfdc8724dd5c74591a
$ docker exec -it mongodb mongo
MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("02a0086f-35f8-4c8c-a615-9769743b22d4") }
MongoDB server version: 4.2.1
Welcome to the MongoDB shell.
(...)
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
Why I can't open mongo shell using single line run command?
I guess that command try to mongo shell start before mongod ready. But I saw few docuements start mongo shell like this. Please let me know why this happend.
When you docker run imagename command, that command runs instead of the normal command the image would run (the CMD from its Dockerfile). When you docker exec containername command, that launches an additional command in the same container. So your docker run example launches the mongo shell instead of running a new database, but by default it tries to connect to a database on localhost, that is, in the same container.
For interacting with databases, my general recommendation would be to install the client tools you need locally and use them directly: run mongo on your host pointing at whatever port you published. You don't need Docker at all (or the root-level privileges it implies) just to make simple client calls. docker exec is in many ways equivalent to ssh'ing as root into the container, and it wouldn't be my preferred path to interacting with a database.
If you do want to docker run a client, you'd have to make it communicate with a server container, using the normal mechanisms for this.
docker network create mongo
docker run -d --net mongo -p 27017:27017 --name mongodb mongo:latest
docker run -it --net mongo mongo:latest \
mongo --host mongodb

Error when connecting to Mongo DB Hosted in a container

Ive installed Docker locally (mac) and tried to run a docker container using the following command.
docker run -it -p 27017:27017 mongoImageId
But when I tried to login in to the container via the mongo terminal client, Im getting the following error.
mongo --port 27017 -u "userName" -p "password" --authenticationDatabase "sampleDBName"
MongoDB shell version v3.6.5
connecting to: mongodb://127.0.0.1:27017/
2018-07-23T13:41:53.423+0530 E QUERY [thread1] Error: network error while attempting to run command 'isMaster' on host '127.0.0.1:27017' :
connect#src/mongo/shell/mongo.js:251:13
#(connect):1:6
exception: connect failed
But if I try to build the same image in an aws ec2 instance, it connects without a hazel. Does any one else also encountered the same issue and was able to find the root cause ?
Ref.
[1] - https://github.com/aashreys/docker-mongo-auth

MongoDB Container Dockerfile no reachable servers

I'm trying to build an easy Dockerfile to Copy files from current directory into container then run a mongorestore command to seed the data. I've looked at many different websites and I'm still getting the following error.
2016-08-17T03:03:22.639+0000 Failed: error connecting to db server: no reachable servers
The command '/bin/sh -c mongorestore --drop /mongo-seed/mongo-seed-data/mongo-dump --host 127.0.0.1:27017' returned a non-zero code: 1
When I "bash" into the container and run the mongorestore command with the same parameters it populates database. I'm at a loss, please help.
Below is the Dockerfile
FROM mongo
COPY . /mongo-seed
EXPOSE 27017
CMD ["mongod"]
RUN mongorestore --drop /mongo-seed/mongo-seed-data/mongo-dump --host 127.0.0.1:27017
CMD is run when you start up the container.
So mongod is not running when docker executes the last RUN instruction of your dockerfile while building the image.
FROM mongo
COPY . /mongo-seed
# EXPOSE 27017 //not necessary, the mongo base image already has that instruction
ENTRYPOINT mongod
Build and run: docker build -t foo . && docker run -d --name bar foo
Execute the mongorestore command:
docker exec bar mongorestore --drop ...