I am trying to set up a 2 node replicaSet in docker for local development only. Single node already works fine, but there are keyfile issues when trying to add a member as part of the docker init script (NB I see the keyfile is set correctly from the logs). The same command works fine from a shell though, not via the init script.
Basically, the current config has worked fine for one node, but adding another gives the following error:
mongo_1 | {"t":{"$date":"2021-07-21T16:33:19.583+00:00"},"s":"W", "c":"REPL", "id":23724, "ctx":"ReplCoord-0","msg":"Got error response on heartbeat request","attr":{"hbStatus":{"code":13,"codeName":"Unauthorized","errmsg":"command replSetHeartbeat requires authentication"},"requestTarget":"mongo-secondary:27017","hbResp":{"ok":1.0}}}
mongo_1 | {"t":{"$date":"2021-07-21T16:33:19.583+00:00"},"s":"E", "c":"REPL", "id":21426, "ctx":"conn2","msg":"replSetInitiate failed","attr":{"error":{"code":74,"codeName":"NodeNotFound","errmsg":"replSetInitiate quorum check failed because not all proposed set members responded affirmatively: mongo-secondary:27017 failed with command replSetHeartbeat requires authentication"}}}
If I remove mongo-secondary
from the set, then after startup use a shell to mongo
to load the exact same config, everything works fine (they keyfile is used and the set is made with both members).
Currently my config is:
# docker-compose.yml
mongo: &MONGO
image: mongo:4.4
restart: unless-stopped
volumes:
- mongo_data:/data/db
- ./scripts/docker/mongo/001_mongo_init.js:/docker-entrypoint-initdb.d/001_mongo_init.js:ro
- ./scripts/docker/mongo/mongo-entrypoint.sh:/mongo-entrypoint
- ./conf/mongodb/mongod-config.yml:/etc/mongod.yml
entrypoint: sh /mongo-entrypoint
ports:
- 27017:27017
env_file:
- ./env/mongo.env
command: --auth --config /etc/mongod.yml
extra_hosts:
- mongo:127.0.0.1
mongo-secondary:
<<: *MONGO
volumes:
- mongo_secondary_data:/data/db
- ./scripts/docker/mongo/mongo-entrypoint.sh:/mongo-entrypoint
- ./conf/mongodb/mongod-config.yml:/etc/mongod.yml
ports:
- 27018:27017
extra_hosts:
- mongo-secondary:127.0.0.1
# mongo-entrypoint.sh
#!/bin/sh
set -eu
# Create the keyfile used for mongo replicaSet auth.
keyfile=/home/keyfile
echo "Creating replicaSet keyfile..."
echo "keyfile" > ${keyfile}
chmod 0400 $keyfile
chown mongodb $keyfile
echo "Created replicaSet keyfile."
# original entrypoint
exec docker-entrypoint.sh "$@"
// 001_mongo_init.js
function getEnv(envVar) {
const ret = run('sh', '-c', `printenv ${envVar} > /tmp/${envVar}.txt`);
if (ret !== 0) throw Error(`Value "${envVar}" is not present in the environment.`);
return cat(`/tmp/${envVar}.txt`).trim(); // NB cat leaves a \n at the end of text
}
// create replicaset
const rsconf = {
_id: getEnv('MONGODB_REPLICA_SET'),
members: [
{
_id: 0,
host: 'mongo:27017',
},
{
_id: 1,
host: 'mongo-secondary:27017',
priority: 0, // prevent from becoming master
},
],
};
rs.initiate(rsconf);
rs.conf();
// further code to create users etc.
# mongod-config.yml
---
security:
keyFile: /home/keyfile
replication:
replSetName: rs0
enableMajorityReadConcern: true