Search code examples
mongodbdockerdocker-composereplicaset

Error "MongoServerError: This node was not started with replication enabled." when setting up replicaset in mongodb (using docker compose)


I'm currently trying to setup a replicaset in my mongodb setup in order to enable Change Streams functionality (which I need for the socket.io MongoDB-Adapter).

Current Setup

I have this service in my docker compose file:

  db:
    build:
      dockerfile: images/Dockerfile_mongodb_dev
    command: ["--config", "/etc/mongo.conf"]
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
    volumes:
      - ./mongodb/mongo.conf:/etc/mongo.conf:ro
      - ./mongodb/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
      - ./data-dev/db:/data/db

The Dockerimage itself is relatively easy and looks like so (with the content of the keyfile replaced for security reasons):

FROM mongo:7.0.6

RUN echo "KEYFILE_CONTENT" >> /etc/mongodb-keyfile && chown mongodb:mongodb /etc/mongodb-keyfile && chmod 400 /etc/mongodb-keyfile

Also, this is what my mongo.conf looks like:

security:
  authorization: enabled
  keyFile: /etc/mongodb-keyfile

net:
  bindIpAll: true
  port: 27027

replication:
  replSetName: rs0

The mongo-init.js looks like this:

rs.initiate({
    _id: 'rs0',
    members: [
        { _id: 0, host: 'db:27017' }
    ]
});

When running the container I then get the error ...

MongoServerError: This node was not started with replication enabled.

... in the console with the service terminating itself.


Solution

  • I solved it with the 7.0.9 mongodb docker image by using the old healthcheck trick.

        healthcheck:
          test: "mongosh -u monitor -p monitor --eval \"try {
              rs.status().ok
            } catch (e) {
              rs.initiate({ '_id': 'rs0', 'members': [{ '_id': 0, 'host': 'localhost:27017' }] }).ok
            }\""
          interval: 10s
          timeout: 30s
          start_period: 2s
          retries: 10
    
    • monitor is a custom user I create via init script in /docker-entrypoint-initdb.d/

    The important thing seems to be that docker-entrypoint.py starts a mongod instance without --replSet and --keyFile and then runs the init scripts against this with mongosh, then it shuts down mongod and starts it with your provided arguments including --replSet. I don#t know the motivation behind this. I tried patching the the docker-entrypoint.py too allow --replSet and --keyFile but it did not work as expected.