13

I'm trying to connect two mongodb containers running on docker using docker-compose. One container seed some data to the other using mongoimport.

However, I'm getting the following error when run mongoimport

Failed: error connecting to db server: no reachable servers

I can actually reach the mongodb container from mongo-seed since I'd appended a ping -c 3 mongodb to the CMD and the container can resolve successfully that hostname.

Below the files I'm using:

docker-compose.yml

version: '2'

services:
  mongodb:
    image: mongo:3.2
    ports:
      - "27017:27017"

  mongo-seed:
    build: ./mongo-seed

mongo-seed/Dockerfile

FROM mongo:3.2

COPY init.json /init.json
CMD ping -c 3 mongodb && mongoimport --host mongodb --db test --collection users \
   --type json --file /init.json --jsonArray

mongo-seed/init.json

[
  {
    "name": "Joe Smith",
    "email": "jsmith@gmail.com",
    "age": 40,
    "admin": false
  },
  {
    "name": "Jen Ford",
    "email": "jford@gmail.com",
    "age": 45,
    "admin": true
  }
]

And this the output of docker-compose up:

mongo-seed_1  | PING mongodb (172.18.0.2): 48 data bytes
mongo-seed_1  | 56 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.116 ms
mongo-seed_1  | 56 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.141 ms
mongo-seed_1  | 56 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.114 ms
mongo-seed_1  | --- mongodb ping statistics ---
mongo-seed_1  | 3 packets transmitted, 3 packets received, 0% packet loss
mongo-seed_1  | round-trip min/avg/max/stddev = 0.114/0.124/0.141/0.000 ms
mongo-seed_1  | 2016-08-09T20:34:15.728+0000    [........................] smtt.devices 0.0 B/25.5 MB (0.0%)
mongo-seed_1  | 2016-08-09T20:34:17.992+0000    [........................] smtt.devices 0.0 B/25.5 MB (0.0%)
mongo-seed_1  | 2016-08-09T20:34:17.992+0000    Failed: error connecting to db server: no reachable servers
mongo-seed_1  | 2016-08-09T20:34:17.992+0000    imported 0 documents
mongo_mongo-seed_1 exited with code 1

Any idea? What am I missing?

Camilo Silva
  • 8,283
  • 4
  • 41
  • 61
  • Ping operates by sending Internet Control Message Protocol (ICMP) Echo Request packets to the target host and waiting for an ICMP Echo Reply. Id does't need a open port on mongo service. Mongo import does need a open port. May be is this your isssue? – Bukharov Sergey Aug 10 '16 at 08:56

2 Answers2

17

I could finally manage to get connected both containers. My findings here for documentation purposes.

Main points

  • docker-compose version 2 creates a bridge network and adds all the containers to it.
  • mongod is not aware of this network and therefore doesn't bind to that ip. By default, binds only to 127.0.0.1
  • mongoimport could not establish connection using container name, even though it's supposed to be translated to the container ip.

Solution

  • Assign an static IP for the mongodb through the explicit definition of a network
  • Init mongo container with --bind_ip flag pointing to that static ip
  • Use ip address instead of hostname with mongoimport

docker-compose.yml

version: '2'

services:
  mongodb:
    image: mongo:3.2
    ports:
      - "27017:27017"
    networks:
      mongo_net:
        ipv4_address: 172.16.0.1
    command: mongod --bind_ip 127.0.0.1,172.16.0.1

  mongo-seed:
    build: ./mongo-seed
    networks:
      mongo_net:
    depends_on:
      - mongodb

networks:
  mongo_net:
    driver: bridge
    ipam:
      config:
      - subnet: 172.16.0.0/24
        gateway: 172.16.0.254

mongo-seed/Dockerfile

FROM mongo:3.2

COPY init.json /init.json
CMD mongoimport --host 172.16.0.1 --db test --collection users \
   --type json --file /init.json --jsonArray
Camilo Silva
  • 8,283
  • 4
  • 41
  • 61
0

Another solution is to use container name as the host name in connection parameters like mongoimport --host my_mongodb or mongo my_mongodb.

Normally, when both application and the mongodb are on the same server or container, you connect to mongodb on localhost ip 127.0.0.1. However, when using docker containers, you can think as if mongodb is on another server. You need to provide that containers address when connecting to mongodb. You can pass the name of the mongodb container to host parameter. This way you won't need to set an ipv4 address for the container.

zarax
  • 871
  • 1
  • 10
  • 30