I had creating a MongoDB replica set using Docker and I can access using console or Robo3T and run any query.
The containers appear like this:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efe6ae03323d mongo "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:30001->27017/tcp mongo1
57d2701c8a43 mongo "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:30002->27017/tcp mongo2
7553966b9ff5 mongo "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:30003->27017/tcp mongo3
The problem is an error when I try to ping using the mongo-go-driver (I tried with version 1.0.0 and 1.0.2)
// Create MongoDB client
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:30001"))
if err != nil {
t.Fatalf("Exit error: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
err = client.Connect(ctx)
if err != nil {
t.Fatalf("Exit error: %v", err)
}
ctx, cancel = context.WithTimeout(context.Background(), time.Minute)
defer cancel()
// Ping
err = client.Ping(ctx, readpref.Primary())
if err != nil {
t.Fatalf("Exit error Ping: %v", err)
}
the error raised by the Ping
call is the following:
Exit error Ping: server selection error: server selection timeout
current topology: Type: ReplicaSetNoPrimary
Servers:
Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host
Addr: mongo3:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo3: no such host
Addr: mongo1:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo1: no such host
Thank you all for the support!
Assuming that the docker is running on your localhost, you can set the name in etc/hosts file like this: So you will be able to run the service both in the docker and from outside, if you'll decide to run only the db in docker Show activity on this post.
It uses golang 1.13.4 and mongodb go driver v1.1.3. Not sure if that would make any difference, but would be good to know. Sorry, something went wrong. @johncarmack1984 I was curious so I tried this on macOS High Sierra after downloading latest monstache and MongoDB community edition 4.2.1. Made only the following changes...
If you are connecting to one docker from another (like it is written in your docker-compose file, and using bridge network mode, you have to change your localhost to the hostname, like datastore When your go script uses localhost, it expects the database to located in the same docker
This is due to unresolved hostname
from Docker host. In Docker, the instances mongo1
, mongo2
, and mongo3
are reachable by those names. However, these names are not reachable from the Docker host. This is evident by this line:
Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host
MongoDB driver will attempt server discovery
from given a replica set member(s); it will find all of other nodes within the replica set (via rs.conf). The problem here is the replica set is set with name mongo<N>
, the driver (run in Docker host) would not be able to resolve these names. You can confirm this by trying to ping mongo1
from Docker host.
You can either try running the application from another Docker instance sharing the same Docker network as the replica set. Or, modify the Docker networking as such to allow resolvable hostnames.
UPDATE:
Regarding your comment on why using mongo shell, or PyMongo works.
This is due to the difference in connection mode. When specifying a single node, i.e. mongodb://node1:27017
in shell or PyMongo, server discovery are not being made. Instead it will attempt to connect to that single node (not as part as a replica set). The catch is that you need to connect to the primary node of the replica set to write (you have to know which one). If you would like to connect as a replica set, you have to define the replica set name.
In contrast to the mongo-go-driver
, by default it would perform server discovery and attempt to connect as a replica set. If you would like to connect as a single node, then you need to specify connect=direct
in the connection URI. See also Example Connect Direct
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With