bitnami/mongodb docker image fails to connect when replica set enabled? - mongodb

I want to use the bitnami/mongodb docker image to spin up a mongodb server for local development. I need to use a single node replica set as my project uses transactions. The image works fine when not configured as a replica set, but when it is Mongo Compass wont connect.
With Replica Set
I'm using docker compose to start the container:
mongodb:
hostname: mongodb
image: bitnami/mongodb:latest
environment:
MONGODB_REPLICA_SET_MODE: primary
MONGODB_REPLICA_SET_NAME: rs0
MONGODB_REPLICA_SET_KEY: 12345
MONGODB_ROOT_PASSWORD: root
volumes:
- mongo-data:/data/db
restart: always
Trying to connect with the following URI comes back with a getaddrinfo ENOTFOUND mongodb error:
mongodb://localhost:27017?replicaSet=rs0
Checking the container's output there doesnt seem to be much information other than it did receive the connection attempt then immediately ended.
2023-02-16 01:16:55 {"t":{"$date":"2023-02-16T09:16:55.854+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:54038","uuid":"87f2d8bc-d254-4824-b1f1-c27e0e9a4558","connectionId":12,"connectionCount":6}}
2023-02-16 01:16:55 {"t":{"$date":"2023-02-16T09:16:55.855+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn12","msg":"client metadata","attr":{"remote":"127.0.0.1:54038","client":"conn12","doc":{"driver":{"name":"nodejs","version":"4.10.0"},"os":{"type":"Windows_NT","name":"win32","architecture":"x64","version":"10.0.22621"},"platform":"Node.js v16.5.0, LE (unified)|Node.js v16.5.0, LE (unified)","application":{"name":"MongoDB Compass Beta"}}}}
2023-02-16 01:16:55 {"t":{"$date":"2023-02-16T09:16:55.869+00:00"},"s":"I", "c":"NETWORK", "id":22944, "ctx":"conn12","msg":"Connection ended","attr":{"remote":"127.0.0.1:54038","uuid":"87f2d8bc-d254-4824-b1f1-c27e0e9a4558","connectionId":12,"connectionCount":5}}
Without Replica Set
If I disable the replica set I can connect just fine:
mongodb:
hostname: mongodb
image: bitnami/mongodb:latest
environment:
MONGODB_ROOT_PASSWORD: root
volumes:
- mongo-data:/data/db
restart: always
mongodb://root:root#localhost:27017

I found my answer through just playing around. What I believe is happening is the bitnami image is initalizing the replicaset with the nodes hostname mongodb and in mongo. When connecting to a replicaset it then seems like its forwarded to try to connect to that hostname, which when running in a docker container often has its own network and is not available on your hosts network. Pinging mongodb fails.
There's two possible solutions to this:
Set the advertised hostname to localhost:
MONGODB_ADVERTISED_HOSTNAME: localhost
Add it to your /hosts file
// C:\Windows\System32\drivers\etc\hosts
127.0.0.1 mongodb

Related

[MongoDB Ops Manager]mongo.mongoUri ops manager db hosts connection not working

I have installed MongoDB Ops Manager Database [3 instances]
/etc/mongod.conf -> bindIp: 0.0.0.0
And I have Installed Ops Manager Application
In /conf/conf-mms.properties my config for mongo.mongoUri is below
mongo.mongoUri=mongodb://1.2.3.4:27017,5.6.7.8:27017,9.10.11.12:27017
Error:
Failure to connect to configured mongo instance: Config{loadBalance=false.....
pre-flight is getting failed
Notes:
mongod is running in all db servers
If single db is mentioned in mongo.mongoUri then application can connect to that database like mongo.mongoUri=mongodb://1.2.3.4:27017
I guess I need to create as replica set as per doc so i tried below command in main database server
mongod --port 27017 --dbpath /home/ubuntu/data/appdb --replSet rs0 --bind_ip localhost,5.6.7.8,9.10.11.12
{"t":{"$date":"2021-01-06T17:36:07.509+00:00"},"s":"E", "c":"STORAGE", "id":20568, "ctx":"initandlisten","msg":"Error setting up listener","attr":{"error":{"code":9001,"codeName":"SocketException","errmsg":"Cannot assign requested address"}}}
Issue is fixed. Single(standalone) database host was able to connect. But for multiple databases to connect we need to implement replica set first for the mongodb databases.

Connecting from external sources to MongoDB replica set in Kubernetes fails with getaddrinfo ENOTFOUND error but standalone works

I have a MongoDB replica set running in Kubernetes (AWS EKS), created using Helm charts from Bitnami. The services are configured to be external facing and set to NodePort.
mongo-mongodb-0-external NodePort 10.100.83.252 27017:30030/TCP
mongo-mongodb-1-external NodePort 10.100.15.184 27017:30031/TCP
mongo-mongodb-2-external NodePort 10.100.90.128 27017:30032/TCP
mongo-mongodb-arbiter-headless ClusterIP None 27017/TCP
mongo-mongodb-headless ClusterIP None 27017/TCP
On my laptop, I can connect Mongo CLI to the replica but connection fails from MongoDB Compass and Studio 3T.
The following works from Mongo CLI from my laptop...
mongo 'mongodb://root:mypassword#k8s_node_ip:30030,k8s_node_ip:30031,k8s_node_ip:30032/mydb?authSource=admin'
...and this works...
mongo admin --host "k8s_node_ip:30030,k8s_node_ip:30031,k8s_node_ip:30032" --authenticationDatabase admin -u root -p mypassword
...but this fails in MongoDB Compass and Studio 3T...
mongodb://root:mypassword#k8s_node_ip:30030,k8s_node_ip:30031,k8s_node_ip:30032/mydb?authSource=admin
The error message is:
getaddrinfo ENOTFOUND mongo-mongodb-0.mongo-mongodb-headless.mynamespace.svc.cluster.local
Bizarrely, the following standalone connection works in Studio 3T:
mongodb://root:mypassword#k8s_node_ip:30030/?serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=admin&authMechanism=SCRAM-SHA-256
When connecting to a replica set, the host:port pairs in the connection string are a seedlist.
The driver/client will attempt to connect to each host in the seedlist in turn until it gets a connection.
It runs the isMaster command to determine which node is primary, and to get a list of all replica set members.
Then is drops the original seedlist connection, and attempts to connect to each replica set member using the host and port information retrieved.
The host information returned by the isMaster usually matches the entry in rs.conf(), which are the hostnames used to initiate the replica set.
In your Kubernetes cluster, the nodes have internal hostnames that are used to initiate the replica set, but that your external clients can't resolve.
In order to get this to work, you will need to have the mongod nodes isMaster command return a different set of hostnames depending on where the client request is coming from. This is similar to split-horizon DNS.
Look over the Deploy a Replica Set documentation for mongodb/kubernetes, and the replicaSetHorizons setting.
Make sure that you have added replica set nodes in the host machine in etc/hosts file.
Just like the below example -
127.0.0.1 mongoset1 mongoset2 mongoset3
Note - 127.0.0.1 is your host machine and mongoset1, mongoset2 and mongoset3 are the nodes (members) of the replicaset.

Cannot connect to docker0 (MongoDB chart)

I am completely new to docker. I followed this instruction to install mongodb chart and docker.
When I connect to 172.17.0.1, it said
Unable to connect to MongoDB using the specified URI.
The following error was returned while attempting to connect:
MongoNetworkError: failed to connect to server [172.17.0.1:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 172.17.0.1:27017]
The result from pinging the specified server "172.17.0.1" from within the container is:
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.050 ms
--- 172.17.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.050/0.050/0.050/0.000 ms
The mongodb is running on local machine. I think it is not running in the container (not sure) because I installed mongodb in my machine before I install docker.
I have also checked the setting by using docker network inspect bridge
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
This is the yml file:
version: "3.3"
services:
charts:
image: quay.io/mongodb/charts:v0.10.0
hostname: charts
ports:
# host:container port mapping. If you want MongoDB Charts to be
# reachable on a different port on the docker host, change this
# to <port>:80, e.g. 8888:80.
- 80:80
- 443:443
volumes:
- keys:/mongodb-charts/volumes/keys
- logs:/mongodb-charts/volumes/logs
- db-certs:/mongodb-charts/volumes/db-certs
- web-certs:/mongodb-charts/volumes/web-certs
environment:
# The presence of following 2 environment variables will enable HTTPS on Charts server.
# All HTTP requests will be redirected to HTTPS as well.
# To enable HTTPS, upload your certificate and key file to the web-certs volume,
# uncomment the following lines and replace with the names of your certificate and key file.
# CHARTS_HTTPS_CERTIFICATE_FILE: charts-https.crt
# CHARTS_HTTPS_CERTIFICATE_KEY_FILE: charts-https.key
# This environment variable controls the built-in support widget and
# metrics collection in MongoDB Charts. To disable both, set the value
# to "off". The default is "on".
CHARTS_SUPPORT_WIDGET_AND_METRICS: "on"
# Directory where you can upload SSL certificates (.pem format) which
# should be considered trusted self-signed or root certificates when
# Charts is accessing MongoDB servers with ?ssl=true
SSL_CERT_DIR: /mongodb-charts/volumes/db-certs
networks:
- backend
secrets:
- charts-mongodb-uri
networks:
backend:
volumes:
keys:
logs:
db-certs:
web-certs:
secrets:
charts-mongodb-uri:
external: true
How can I connect to the mongodb?
By default mongodb is configured to only accept results from localhost 127.0.0.1 and when charts image connects to it via docker it is seen as an external connection coming from docker0 and it is hence rejected by mongod [MongoNetworkError: connect ECONNREFUSED 172.17.0.1:27017]
To fix this, edit the mongo config sudo vim /etc/mongod.conf and add your docker0 ip to the bindIp config the line with bindIp: 127.0.0.1 should be changed to bindIp: 127.0.0.1,172.17.0.1 for default docker installations.
This may be an old question but I think it could be a common issue, I had to struggle with this for a while before actually reading the error message more thoroughly and realising it really a simple issue.
Another issue is that the upon first install you can connect to mongo without a username or password, so those two should be deleted from the uri if you had not configured security, making it mongodb://172.17.0.1:27017.
Assuming you know how to use echo "mongodb://<username>:<password>#myhost.com/" | docker secret create charts-mongodb-uri - to create the connection the url.
The problem is actually how to connect from a docker container to a outside service running on the host machine. You can use some help from plenty of questions like From inside of a Docker container, how do I connect to the localhost of the machine?
Basically, if you are using docker for mac or windows, use something like echo "mongodb://host.docker.internal" | docker secret create charts-mongodb-uri -, for linux see https://docs.mongodb.com/charts/master/installation/ section RUNNING METADATA DATABASE ON LOCALHOST for the doc, or just use host mode (remove ports section)
version: "3.3"
services:
charts:
image: quay.io/mongodb/charts:v0.10.0
hostname: charts
network_mode: "host"
...

connect robomongo to mongoDB docker container

I'm running a NodeJS App with docker-compose. Everything works fine and I can see all my data by connecting to Mongo inside container. But when I connect to RoboMongo I don't see any data.
How can I deal with this problem?
There is another way. You can
SSH with Robomongo into your actual virtual server that hosts your docker applications (SSH tab, check "Use SSH tunnel" and complete the other fields accordingly)
Now ssh into the same machine in your terminal.
docker ps should show you your MongoDB container.
docker inspect <mongo container id> will print out complete information about that container. Look for IPAddress in the end, that will give you the local IP of the container.
In the "Connection" tab in Robomongo use that container IP to connect.
Another sidenote: Make sure that you don't expose your mongodb service ports in any way (neither Dockerfile nor docker-compose.yml), cause that will make your database openly accessible from everywhere. Assuming that you don't have set up a username / password for that service you will be scanned and hacked soon.
The easiest way is to enable forwarding the Mongo Container itself, here's how my docker-compose looks like.
mongo:
image: mongo
restart: always
ports:
- 27017:27017
You should do a Robomongo SSH tunnel connection to MongoDB inside docker container. First of all you should install a ssh server inside your docker container.
https://docs.docker.com/engine/examples/running_ssh_service/
After that you should configure your connection in Robomongo.
Inside "Connection Settings" there are configuration tabs of your Robomongo Connection.
Go to "SSH" Tab and configure your SSH connection to the docker container. After that go to "Connection" Tab and configure your connection to MongoDB as if it was in localhost scope.
I was facing a different problem. I had installed MongoDB locally. So, when the MongoDB on docker was running, it was clashing with the one running on my host. I had installed it using brew.
So, I ran
brew services stop mongodb-community
and then I restarted Robo3t. I saw the databases created in the MongoDB running on the docker.
Voila!
Please note that maybe you won't be able to use ssh because it was just a problem of incompatibility between mongo and robomongo.
'Robomongo v8.5 and lower doesn't support MongoDB 3'. It has nothing to do with docker.
First log in with ssh Login details
ssh -i yourpemfile.pem username#ipaddress
Check running container id for MongoDB
docker ps -a
then check the mongo container id
docker inspect container_id
Then open robo3t
create new connection and add container id
use ssh login details to connect to mongodb
In your docker-compose file, you can expose a port to the host.
For example, the following code will expose port 27017 inside the machine to the port 27018 in the host.
app:
image: node
volumes:
- /app
ports:
- "27018:27017"
Then, if you have docker-machine installed and your machine is default, you can do in a terminal :
docker-machine ip default
It will give you the ip of your host, for example 192.168.2.3. The address of your database (host) will be 192.168.2.3 and the port 27018.
If your docker machine is not virtual and is your OS, the address of your database will be localhost and the port 27018.

Unable to connect to mongoDB running in docker container

Following this example: https://docs.docker.com/engine/examples/mongodb/
When trying to connect to mongoDB with: mongo ip:27017
(where ip is the name from boot2docker ip) + the port number from docker ps:
27017/tcp
or with -P
0.0.0.0:49155->27017/tcp
Either way I get the following errors:
warning: Failed to connect to ip:27017, reason: errno:61 Connection
refused
Error: couldn't connect to server ip:27017 (ip), connection attempt
failed at src/mongo/shell/mongo.js:148 exception: connect failed
If you specified the correct port and still not able to connect to mongodb running in docker (like me), make sure you are using the service name (or container name) in your connection URL, e.g. mongodb://mongodb_service:27017/mydb, which is defined in your docker-compose.yml :
services:
mongodb_service:
image: mongo
I was using the hostname value and that's not the correct thing to do. You could verify this by looking at docker inspect mongodb_service in the Aliases section.
I was using port 27017 instead of 49155 (doh, port forwarding)
0.0.0.0:49155->27017/tcp
Thanks to ZeissS
If you are on a Mac and using Docker Machine, do the following:
1. Get the name of the VM running docker daemon
$ docker-machine ls
2. Get the VM's IP info
$ docker-machine env
3. Connect with the mongo client to the VM IP and the mongo mapped port
$ mongo VM-IP:port
Assuming your mongodb is within a container, for other containers to connect to it, they all need to be on the same network.
To have mongodb and other containers (that want to connect it), create a new network using below command
docker network create --driver bridge my_bridge
Then run mongodb and other containers using the --net flag
docker run --net=my_bridge --name mongodb -p 27017:27017 mongodb
docker run --net=my_bridge --name my-service -p 7002:7002 my-service
Now you should be able to connect mongodb with given alias name from those containers
mongo --host "mongodb:27017"
DATABASE_URI=mongodb://mongo:27017/db_name
Should be the Database URI for a service definition like below (and not mongodb://localhost
or mongodb://IP). Use service name or container name.
services
mongo:
container_name: mongo
image: mongo
ports:
- '27017:27017'