1

I'm using docker-compose for mongodb replica set. Everything work fine on my host where docker is running. I had problems when I tried to connect from another client which is in the same network.I have exposed ports in my docker.

version: '3.2'
networks:
    netBackEnd:
        ipam:
            driver: default
            config:
                 - subnet: 192.168.0.0/24
services:
 
    mongo1:
        hostname: mongo1
        container_name: mongo1
        image: mongo:4.2-bionic
        expose:
            - 27017
        ports:
            - 27017:27017
        restart: always
        volumes:
            - "/etc/mongodb/ssl/mongo1.pem:/data/mongo1.pem:ro"
            - "/etc/mongodb/ssl/testing.ca.crt:/data/testing.ca.crt:ro"
            - "/usr/local/mongo-volume1:/data/db"
        command: --replSet rs0 --sslMode requireSSL --clusterAuthMode x509 --sslClusterFile /data/mongo1.pem --sslPEMKeyFile /data/mongo1.pem --sslCAFile /data/testing.ca.crt --bind_ip 0.0.0.0 --port 27017
        networks:
           netBackEnd:
               ipv4_address: 192.168.0.2

    mongo2:
        hostname: mongo2
        container_name: mongo2
        image: mongo:4.2-bionic
        expose:
            - 27018
        ports:
            - 27018:27018
        restart: always
        volumes:
            - "/etc/mongodb/ssl/mongo2.pem:/data/mongo2.pem:ro"
            - "/etc/mongodb/ssl/testing.ca.crt:/data/testing.ca.crt:ro"
            - "/usr/local/mongo-volume2:/data/db"
        command: --replSet rs0 --sslMode requireSSL --clusterAuthMode x509 --sslClusterFile /data/mongo2.pem --sslPEMKeyFile /data/mongo2.pem --sslCAFile /data/testing.ca.crt  --bind_ip 0.0.0.0 --port 27018
        networks:
           netBackEnd:
               ipv4_address: 192.168.0.3
    mongo3:
        hostname: mongo3
        container_name: mongo3
        image: mongo:4.2-bionic
        expose:
            - 27019
        ports:
            - 27019:27019
        restart: always
        volumes:
            - "/etc/mongodb/ssl/mongo3.pem:/data/mongo3.pem:ro"
            - "/etc/mongodb/ssl/testing.ca.crt:/data/testing.ca.crt:ro"
            - "/usr/local/mongo-volume3:/data/db"
        command: --replSet rs0 --sslMode requireSSL --clusterAuthMode x509 --sslClusterFile /data/mongo3.pem --sslPEMKeyFile /data/mongo3.pem --sslCAFile /data/testing.ca.crt --bind_ip 0.0.0.0 --port 27019
        networks:
           netBackEnd:
               ipv4_address: 192.168.0.4

/etc/hosts file where the docker is running

127.0.0.1   localhost
127.0.1.1   xxxx-ThinkPad-X270
192.168.0.1    mongo1
192.168.0.2     mongo2
192.168.0.3     mongo3

I can connect to individual host using ip_address of the host where docker is running but not to complete replica set as replica set only works when uses the same host-names as in the replica set initialization.

mongo --ssl --sslCAFile /etc/mongodb/ssl/testing.ca.crt --host host_ip_address:27017 --sslPEMKeyFile /etc/mongodb/ssl/remote_client.pem --authenticationDatabase '$external' --authenticationMechanism 'MONGODB-X509'

But not uisng below connection string

mongo --ssl --sslCAFile /etc/mongodb/ssl/testing.ca.crt --host rs0/host_ip_address:27017,host_ip_address:27018,host_ip_address:27019 --sslPEMKeyFile /etc/mongodb/ssl/client.pem --authenticationDatabase '$external' --authenticationMechanism 'MONGODB-X509'

So I thought of using nginx server as reverse proxy to my replica set. but again the same problem I can only connect to individual host.

nginx config file

stream {
    server {
        listen  27020 so_keepalive=on;
        proxy_connect_timeout 20s;
        proxy_pass    stream_mongo_backend;
        proxy_timeout 10m;
    }

    upstream stream_mongo_backend {
         server  mongo1:27017;
         server  mongo1:27018;
         server  mongo1:27019;
    }

}

Connection string

mongo --ssl --sslCAFile /etc/mongodb/ssl/testing.ca.crt --host rs0/host_ip_address:27020 --sslPEMKeyFile /etc/mongodb/ssl/remote_client.pem --authenticationDatabase '$external' --authenticationMechanism 'MONGODB-X509

I have found the below post regarding replicaset config behind proxy. I haven't completely understood the solution and I'm looking something for docker and using nginx.

Any idea where it's going wrong.

  • Using the same network alias (e.g. mongo) for all three containers could do the trick: (see: https://docs.docker.com/compose/compose-file/compose-file-v3/#aliases). Each user defined docker network hasbuil -in dns based service discovery - using the same alias on the services, should result in a multi value dns entry (see: https://docs.docker.com/network/bridge/#differences-between-user-defined-bridges-and-the-default-bridge). – Metin Jan 23 '21 at 15:08
  • @Metin, Thanks for the reply. Even if add network alias, it will still be limited to docker-network right? because the network alias still may be not accessible from host machine network? Do I need to run my nginx also in the docker. because at the moment I'm running nginx on my host machine not in docker. – user3792685 Jan 25 '21 at 01:04
  • Aliases in container networks are of course only available in the container network. You might want to containerize your nginx as well. Make sure to not suffer from cached dns lookups: https://forums.docker.com/t/nginx-swarm-redeploy-timeouts/68904/5 – Metin Jan 27 '21 at 20:48
  • 1
    Did you actual perform rs.initiate() to setup the members of your replicaSet in the mongo shell? You followed a tutorial like https://docs.mongodb.com/manual/tutorial/deploy-replica-set-for-testing/, didn't you? The shared alias realy just makes sense if you consumer is also containerized. Otherwise you nginx will remain the single point of entry. – Metin Jan 27 '21 at 20:57
  • Hi @Metin, Thanks for the reply. I'm trying to solve it by using evreything in docker using docker-swarm so that my machines can communicate easily. But I still wonder if there is any solution to communicate between mongodb replica set on docker and remote client running locally. – user3792685 Jan 29 '21 at 01:57
  • Of course the remote client needs to query the published host port of your containerized nginx reverse proxy, which forwards the request to the mongodb instances, which return their response back to the nginx rp, which itself returns the response to the remote client.. Just to be sure: you are aware that declaring your physical network's ip range in a docker bridged/overlay network does not magicaly make the containers part of your physical network, aren't you? – Metin Jan 29 '21 at 16:46
  • @MetinYes, I'm aware of that. The problem is mogodb tries to resolve the hostnames on the remote-client even if i try to connect using nginx reverse proxy. I'm not sure how i can resolve the hostnames on the remote client as docker is in private network. The whole point of reverse-proxy not really working for replica set. – user3792685 Feb 02 '21 at 04:54

0 Answers0