Unable to open Mongo shell using Docker run but exec - mongodb

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

Related

Can authenticate to docker mongo instance with CLI, but not by any other means

I have a bitnami mongo image that i start using:
docker run -p 27017:27017 -it --name mongodb <myregistry>.azurecr.io/movo.mongodb
I seed the mongo database using a script from which the output can be seen on the left hand of the image.
The problem:
I can connect the database using the mongo-cli.
However, i can't authenticate using Robo3T or my C# solution, using an identical connectionstring..
This works:
docker exec -it mongodb mongo admin -u movoproto -p "...<MyPwd>..."
But i cannot authenticate in any other way.
The connection does not seem to be the problem...
I've got an identical setup on my laptop where it workes fine...
After some fiddling i figured out what the issue was in the end.
It appears mongodb on windows can start as a local service, which runs a database on 127.0.0.1:27017.
So using Robo3T I was connecting to this local instance instead of my mapped docker mongo instance.
With Robo3T i could connect to this local instance when i unticked 'Perform Authentication'.
In Robo3T you can choose -> Right-click 'Open shell' -> db.hostInfo() -> F5 -> View results in text mode.
This would give info about my desktop computer
Whereas docker exec -it mongodb mongo --eval 'db.hostInfo()' would display information regarding my docker image.
My solution was to disable the mongo service on my desktop pc that runs the local database.
Doing this would let docker run -p 27017:27017 -it --name mongodb <myregistry>.azurecr.io/movo.mongodb bind to my docker container at 127.0.0.1:27017

Mongo docker image - unable to run on different port

There are a tons of question here on SO citing how this command alone
docker run --name mymongo --network bridge -p 27117:27117 -v "$PWD/db":/data/db -d mongo
should run mongo on port 27117.
However this doesn't work for me. The container runs, but the mongo is run on its default port alone (see output from container itself):
# mongo
MongoDB shell version v4.0.4
connecting to: mongodb://127.0.0.1:27017
# mongo --port 27117
MongoDB shell version v4.0.4
connecting to: mongodb://127.0.0.1:27117/
2018-11-20T17:26:09.345+0000 E QUERY [js] Error: couldn't connect to server 127.0.0.1:27117, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27117 :: caused by :: Connection refused :
What is going on?
Thanks a lot!
Inside your container mongo runs on its default port, which is 27017
So, you should modify your command and specify the port mapping like this: -p 27117:27017
The full command would be this:
docker run --name mymongo --network bridge -p 27117:27017 -v "$PWD/db":/data/db -d mongo
With that command you are telling docker that the port is 27117, but you also need to start mongo with that port.
To do so, just add --port 27117 at the end of your command:
docker run --name mymongo --network bridge -p 27117:27117 -v "$PWD/db":/data/db -d mongo --port 27117

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

How to allow remote connections from mongo docker container

I am using the official mongodb docker container.
I want to connect to the mongodb container from my host machine on port 27017.
I ran the container with these ports exposed
-p 27017:27017
I am not able to connect (connection refused) and I believe its because the mongo conf file is not configured to allow remote connections. How can I configure it to allow? The official container does not have vi/nano installed to modify the image.
I am able to connect to mongodb from another container by creating a link - however this is not my wish
Better solutions for furthering:
https://blog.madisonhub.org/setting-up-a-mongodb-server-with-auth-on-docker/
https://docs.mongodb.com/v2.6/tutorial/add-user-administrator/
My answer to another question. How to enable authentication on MongoDB through Docker?
Here's what I did for the same problem, and it worked.
Run the mongo docker instance on your server
docker run -d -p 27017:27017 -v ~/dataMongo:/data/db mongo
Open bash on the running docker instance.
docker ps
CONTAINER IDIMAGE COMMAND CREATED STATUS PORTS NAMES
b07599e429fb mongo "docker-entrypoint..." 35 minutes ago Up 35 minutes 0.0.0.0:27017->27017/tcp musing_stallman
docker exec -it b07599e429fb bash
root#b07599e429fb:/#
Reference- https://github.com/arunoda/meteor-up-legacy/wiki/Accessing-the-running-Mongodb-docker-container-from-command-line-on-EC2
Enter the mongo shell by typing mongo.
root#b07599e429fb:/# mongo
For this example, I will set up a user named ian and give that user read & write access to the cool_db database.
> use cool_db
> db.createUser({
user: 'ian',
pwd: 'secretPassword',
roles: [{ role: 'readWrite', db:'cool_db'}]
})
Reference: https://ianlondon.github.io/blog/mongodb-auth/ (First point only)
Exit from mongod shell and bash.
Now run the mongo docker with auth enabled.
docker run -d -p 27017:27017 -v ~/dataMongo:/data/db mongo mongod --auth
Reference: How to enable authentication on MongoDB through Docker? (Usman Ismail's answer to this question)
I was able to connect to the instance running on a Google Cloud server from my local windows laptop using the below command.
mongo <ip>:27017/cool_db -u ian -p secretPassword
Reference: how can I connect to a remote mongo server from Mac OS terminal

Node / Express app can't connect to docker mongodb

I want to run a node app that uses express and connects to a (boot2docker) docker mongo container.
When I first wrote the app, I was using a locally installed instance of mongodb, and the following config worked:
module.exports = {
env: 'development',
mongo: {
uri: 'mongodb://localhost/fullstack-dev'
}
};
And it ran as expected.
Now I'm trying to swap that out for a docker instance of mongo.
So, I've done the following steps to get mongo running:
$ docker pull mongo:latest
$ docker run -v "$(pwd)":/data --name mongo -d mongo mongod --smallfiles
$ docker ps
#my mongo instance is 442c2541fe1a
$ docker exec -it 442c2541fe1a bash
$ mongo
At this point, appears to be running in my command prompt.
Then, I tried to get the IP of boot2docker vm that runs docker on osx:
$ boot2docker ip
# the IP returned: 192.168.59.103
So, then, I went to swap out the old mongodb path in the nodejs config to the following:
module.exports = {
env: 'development',
mongo: {
uri: 'mongodb://192.168.59.103:27017/fullstack-dev'
}
};
and when I run the application, I get a connection error.
events.js:72
throw er; // Unhandled 'error' event
^
Error: failed to connect to [192.168.59.103:27017]
What is the proper config for connecting my MEAN stack application with a docker'ified mongodb instance?
You need to publish the appropriate port on the container with the -p argument i.e:
docker run -p 27017:27017 -v "$(pwd)":/data --name mongo -d mongo mongod --smallfiles
The will make port 27017 accessible on the host (the VM in your case) and forward traffic to port 27017 on the container.