Can't connect to MongoDB with Replica Set running as a container in localhost

569 Views Asked by At

This is a fairly simple scenario and I cannot figure out why it's not working.

I have a docker compose

version: '3.8'

services:
  mongodb:
    image: mongo:latest
    command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
    ports:
      - "27017:27017"

I run docker-compose up to spin it up

And I can see some logs

sandbox-mongodb-1  | {"t":{"$date":"2023-12-21T18:46:26.001+00:00"},"s":"W",  "c":"QUERY",    "id":23799,   "ctx":"ftdc","msg":"Aggregate command executor error","attr":{"error":{"code":26,"codeName":"NamespaceNotFound","errmsg":"Unable to retrieve storageStats in $collStats stage :: caused by :: Collection [local.oplog.rs] not found."},"stats":{},"cmd":{"aggregate":"oplog.rs","cursor":{},"pipeline":[{"$collStats":{"storageStats":{"waitForLock":false,"numericOnly":true}}}],"$db":"local"}}}
sandbox-mongodb-1  | {"t":{"$date":"2023-12-21T18:46:26.128+00:00"},"s":"I",  "c":"-",        "id":4939300, "ctx":"monitoring-keys-for-HMAC","msg":"Failed to refresh key cache","attr":{"error":"ReadConcernMajorityNotAvailableYet: Read concern majority reads are currently not possible.","nextWakeupMillis":800}}
sandbox-mongodb-1  | {"t":{"$date":"2023-12-21T18:46:26.929+00:00"},"s":"I",  "c":"-",        "id":4939300, "ctx":"monitoring-keys-for-HMAC","msg":"Failed to refresh key cache","attr":{"error":"ReadConcernMajorityNotAvailableYet: Read concern majority reads are currently not possible.","nextWakeupMillis":1000}}
sandbox-mongodb-1  | {"t":{"$date":"2023-12-21T18:46:27.001+00:00"},"s":"W",  "c":"QUERY",    "id":23799,   "ctx":"ftdc","msg":"Aggregate command executor error","attr":{"error":{"code":26,"codeName":"NamespaceNotFound","errmsg":"Unable to retrieve storageStats in $collStats stage :: caused by :: Collection [local.oplog.rs] not found."},"stats":{},"cmd":{"aggregate":"oplog.rs","cursor":{},"pipeline":[{"$collStats":{"storageStats":{"waitForLock":false,"numericOnly":true}}}],"$db":"local"}}}
sandbox-mongodb-1  | {"t":{"$date":"2023-12-21T18:46:27.930+00:00"},"s":"I",  "c":"-",        "id":4939300, "ctx":"monitoring-keys-for-HMAC","msg":"Failed to refresh key cache","attr":{"error":"ReadConcernMajorityNotAvailableYet: Read concern majority reads are currently not possible.","nextWakeupMillis":1200}}
sandbox-mongodb-1  | {"t":{"$date":"2023-12-21T18:46:28.001+00:00"},"s":"W",  "c":"QUERY",    "id":23799,   "ctx":"ftdc","msg":"Aggregate command executor error","attr":{"error":{"code":26,"codeName":"NamespaceNotFound","errmsg":"Unable to retrieve storageStats in $collStats stage :: caused by :: Collection [local.oplog.rs] not found."},"stats":{},"cmd":{"aggregate":"oplog.rs","cursor":{},"pipeline":[{"$collStats":{"storageStats":{"waitForLock":false,"numericOnly":true}}}],"$db":"local"}}}

Now I do a

docker ps

and I can see the container Id

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                      NAMES
fdea0af9dc8e   mongo:latest   "docker-entrypoint.s…"   12 minutes ago   Up 12 minutes   0.0.0.0:27017->27017/tcp   sandbox-mongodb-1

I can connect to it with mongosh

$ docker exec -it 5d44bda7d148 mongosh
Current Mongosh Log ID: 658488458e2ace9369e0f846
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.1.1
Using MongoDB:          7.0.4
Using Mongosh:          2.1.1

For mongosh info see: https://docs.mongodb.com/mongodb-shell/


To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.

------
   The server generated these startup warnings when booting
   2023-12-21T18:46:24.293+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
   2023-12-21T18:46:24.911+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
   2023-12-21T18:46:24.911+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
   2023-12-21T18:46:24.911+00:00: vm.max_map_count is too low
------

I initialize the replica set

test> rs.initiate()
{
  info2: 'no configuration specified. Using a default configuration for the set',
  me: '5d44bda7d148:27017',
  ok: 1
}

And I can see current config

rs0 [direct: other] test> rs.config()
{
  _id: 'rs0',
  version: 1,
  term: 1,
  members: [
    {
      _id: 0,
      host: '5d44bda7d148:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      secondaryDelaySecs: Long('0'),
      votes: 1
    }
  ],
  protocolVersion: Long('1'),
  writeConcernMajorityJournalDefault: true,
  settings: {
    chainingAllowed: true,
    heartbeatIntervalMillis: 2000,
    heartbeatTimeoutSecs: 10,
    electionTimeoutMillis: 10000,
    catchUpTimeoutMillis: -1,
    catchUpTakeoverDelayMillis: 30000,
    getLastErrorModes: {},
    getLastErrorDefaults: { w: 1, wtimeout: 0 },
    replicaSetId: ObjectId('6584887336c122ec814c9914')
  }
}

Now I open, on my host (Windows) 3T studio and I create connections.

This connection string works well

mongodb://127.0.0.1:27017

This connection string does not connect

mongodb://127.0.0.1:27017/?replicaSet=rs0&ssl=false

Why?

Apparently the replica set is running properly and it's obvious I can reach the server

This is the timeout error 3T Studio shows

SERVER [5d44bda7d148:27017] (Type: UNKNOWN) 
|_/ Connection error (MongoSocketOpenException): Exception opening socket
|____/ Unknown host: 5d44bda7d148

Details:
Timed out after 30000 ms while waiting for a server that matches com.mongodb.client.internal.MongoClientDelegate$1@482d37d9. Client view of cluster state is {type=REPLICA_SET, servers=[{address=5d44bda7d148:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.UnknownHostException: 5d44bda7d148}}]

I need to have MongoDb replica set running as a docker container locally, because I need it for local development with change streams. I'd appreciate an explanation and a solution.


UPDATE 1 (2023-12-21) I have also tried with

command: ["mongod", "--replSet", "rs0", "--bind_ip", "localhost"]

in docker compose, as per https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/#ip-binding but no luck

1

There are 1 best solutions below

1
On

It seems the problem was with the host that the replica set is configured by default. It seems to pick the container ID, which is not what I want.

If I connect with mongosh and do this:

let cfg = rs.config()
cfg.members[0].host = 'localhost:27017'
rs.reconfig(cfg)

essentially modifying the host so that now it looks like

rs0 [direct: primary] test> rs.config()
{
  _id: 'rs0',
  version: 3,
  term: 1,
  members: [
    {
      _id: 0,
      host: '127.0.0.1:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      secondaryDelaySecs: Long('0'),
      votes: 1
    }
  ],
  protocolVersion: Long('1'),
  writeConcernMajorityJournalDefault: true,
  settings: {
    chainingAllowed: true,
    heartbeatIntervalMillis: 2000,
    heartbeatTimeoutSecs: 10,
    electionTimeoutMillis: 10000,
    catchUpTimeoutMillis: -1,
    catchUpTakeoverDelayMillis: 30000,
    getLastErrorModes: {},
    getLastErrorDefaults: { w: 1, wtimeout: 0 },
    replicaSetId: ObjectId('6584bfe7812f7983ae2da944')
  }
}

I can now connect from my host to

mongodb://localhost:27017/?replicaSet=rs0

It feels hacky, but it seems to work.


UPDATE

Another cleaner option would be to connect to mongosh and do this instead, to pass configuration without having to reconfigure

test> const configuration = { _id: "rs0", members: [{ _id: 0, host: "127.0.0.1:27017"}]}

test> rs.initiate(configuration)

which gives me a similar result in which the host has 127.0.0.1 or localhost instead of the container id.