skip to Main Content

I have been trying to dockerize my spring boot application which depends on redis, kafka and mongodb.

Following is the docker-compose.yml:

version: '3.3'
services:
  my-service:
    image: my-service
    build:
      context: ../../
      dockerfile: Dockerfile
    restart: always
    container_name: my-service
    environment:
      KAFKA_CONFLUENT_BOOTSTRAP_SERVERS: kafka:9092
      MONGO_HOSTS: mongodb:27017
      REDIS_HOST: redis
      REDIS_PORT: 6379

    volumes:
      - /private/var/log/my-service/:/var/log/my-service/
    ports:
      - 8080:8090
      - 1053:1053

    depends_on:
      - redis
      - kafka
      - mongodb

  portainer:
    image: portainer/portainer
    command: -H unix:///var/run/docker.sock
    restart: always
    container_name: portainer
    ports:
      - 9000:9000
      - 9001:8000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  redis:
    image: redis
    container_name: redis
    restart: always
    ports:
      - 6379:6379

  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - 2181:2181
    container_name: zookeeper

  kafka:
    image: wurstmeister/kafka
    ports:
      - 9092:9092
    container_name: kafka
    environment:
      KAFKA_CREATE_TOPICS: "cms.entity.change:1:1" # topic:partition:replicas
      KAFKA_ADVERTISED_HOST_NAME: kafka
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_PORT: 9092
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - "zookeeper"

  mongodb:
    image: mongo:latest
    container_name: mongodb
    environment:
      MONGO_INITDB_ROOT_USERNAME:
      MONGO_INITDB_ROOT_PASSWORD:
    ports:
      - 27017:27017
    volumes:
      - ./data/db:/data/db

The issue is that this starts up mongo as a STANDALONE instance. So the APIs in my service that persist data are failing as mongo needs to start as a REPLICA_SET.

How can I edit my docker-compose file to start mongo as a REPLICA_SET?

2

Answers


  1. Edited:
    my previous answer was far wrong so I changed it. I managed to make it work using 'bitnami/mongodb:4.0'. Not sure if that would help you or not, but maybe it gives you some idea. They have a docker-compose file ready for replicaset mode.

    version: '3'
    
    services:
      mdb-primary:
        image: 'bitnami/mongodb:4.0'
        environment:
          - MONGODB_REPLICA_SET_MODE=primary
          - MONGODB_ROOT_PASSWORD=somepassword
          - MONGODB_REPLICA_SET_KEY=replicasetkey
          - MONGODB_ADVERTISED_HOSTNAME=mdb-primary
    
      mdb-secondary:
        image: 'bitnami/mongodb:4.0'
        depends_on:
          - mdb-primary
        environment:
          - MONGODB_PRIMARY_HOST=mdb-primary
          - MONGODB_REPLICA_SET_MODE=secondary
          - MONGODB_PRIMARY_ROOT_PASSWORD=somepassword
          - MONGODB_REPLICA_SET_KEY=replicasetkey
          - MONGODB_ADVERTISED_HOSTNAME=mdb-secondary
    
      mdb-arbiter:
        image: 'bitnami/mongodb:4.0'
        depends_on:
          - mdb-primary
        environment:
          - MONGODB_PRIMARY_HOST=mdb-primary
          - MONGODB_REPLICA_SET_MODE=arbiter
          - MONGODB_PRIMARY_ROOT_PASSWORD=somepassword
          - MONGODB_REPLICA_SET_KEY=replicasetkey
          - MONGODB_ADVERTISED_HOSTNAME=mdb-arbiter 
    
      mongo-cli:
        image: 'bitnami/mongodb:latest'
    
    

    don’t forget to add volumes and map it to /bitnami on the primary node

    the last container, mongo-cli is for testing purposes. So you can connect to the replicaset using the cli, there is an argument about that here if you like to read about it.

    $ docker-compose exec mongo-cli bash
    $ mongo "mongodb://mdb-primary:27017/test?replicaSet=replicaset"
    
    Login or Signup to reply.
  2. I had the same issue and ended up on this stackoverflow post.

    We had a requirement of using official mongoDB docker image (https://hub.docker.com/_/mongo ) and couldn’t use bitnami as suggested in Vahid’s answer.

    This answer isn’t exactly what’s needed by the question asked and coming in 6 months too late; but it should give directions to someone who need to use the mongoDb standalone replicaset throw away instance for integration testing purpose. If you need to use it in PROD then you’ll have to provide environment variables for volumes and auth as per Vahid’s answer.

    version: '3.7'
    services:
      mongodb:
        image: mongo:latest
        container_name: myservice-mongodb
        networks:
          - myServiceNetwork
        expose:
          - 27017
        command: --replSet singleNodeReplSet
      mongodb-replicaset:
        container_name: mongodb-replicaset-helper
        depends_on:
          - mongodb
        networks:
          - myServiceNetwork
        image: mongo:latest
        command: bash -c "sleep 5 && mongo --host myservice-mongodb --port 27017 --eval "rs.initiate()" && sleep 2 && mongo --host myservice-mongodb --port 27017 --eval "rs.status()" && sleep infinity"
      my-service:
        depends_on:
          - mongodb-replicaset
        image: myserviceimage
        container_name: myservicecontainer
        networks:
          - myServiceNetwork
        environment:
          myservice__Database__ConnectionString: mongodb://myservice-mongodb:27017/?connect=direct&replicaSet=singleNodeReplSet&readPreference=primary
          myservice__Database__Name: myserviceDb
    
    networks:
      myServiceNetwork:
        driver: bridge
    

    NOTE: Please look at the way how connection string is passed as env variable to the service depending on mongo replicaset instance. You’d have to ensure that the name used in setting up the mongodb replicaset (in my case singleNodeReplicaSet) is passed on to the service depending on it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search