Alex Polkhovsky
Alex Polkhovsky

Reputation: 3360

Connect to meteor mongo from local docker image on Mac

meteor mongo -U shows me mongodb://127.0.0.1:3001/meteor as the connection string. I understand that the docker image will try to connect to itself and fail. I tried substituting 127.0.0.1 for any IP address I could find when running ifconfig with the same result:

{ [MongoError: connect ECONNREFUSED xxx.xxx.xxx.xxx:3001]
  name: 'MongoError',
  message: 'connect ECONNREFUSED xxx.xxx.xxx.xxx:3001' }

Not sure what else I can try to resolve this. Any pointers will be appreciated.

More Information: mongo 127.0.0.1:3001/meteor works from a different shell window. But no other IP addresses work: mongo 10.0.0.96:3001/meteor:

2015-11-16T10:16:14.089-0500 W NETWORK  Failed to connect to 10.0.0.96:3001, reason: errno:61 Connection refused
2015-11-16T10:16:14.091-0500 E QUERY    Error: couldn't connect to server 10.0.0.96:3001 (10.0.0.96), connection attempt failed
    at connect (src/mongo/shell/mongo.js:181:14)
    at (connect):1:6 at src/mongo/shell/mongo.js:181
exception: connect failed

====================== Additional set up information ====================

create a basic meteor app: meteor create app cd app meteor . In another terminal in the same folder app run meteor mongo -U to get connection string: mongodb://127.0.0.1:3001/meteor. Now in a different folder create a node app that wants to connect to a mongo db: mkdir worker, cd worker, npm install mongodb, create worker.js:

var MongoClient = require('mongodb').MongoClient;

// Use connect method to connect to the Server
MongoClient.connect("mongodb://127.0.0.1:3001/meteor", function(err, db) {

    if (err){
        console.log(err);
    }else{
        console.log("Connected correctly to server");
    }

});

and finally run in docker:

docker run --rm -v "$(pwd)":/worker -w /worker iron/images:node-4.1 sh -c "node worker.js"

docker IP address is 192.168.99.100 One of the IP addresses I have listed from ifconfig is

vboxnet0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    ether 0a:00:27:00:00:00 
    inet 192.168.99.1 netmask 0xffffff00 broadcast 192.168.99.255

I plug it in, run the docker command and get this:

{ [MongoError: connect ECONNREFUSED 192.168.99.1:3001]
  name: 'MongoError',
  message: 'connect ECONNREFUSED 192.168.99.1:3001' }

Upvotes: 3

Views: 920

Answers (1)

Rico
Rico

Reputation: 61531

So assuming here that you are running your meteor app in your local Mac and then your docker container for your node app is running in a docker-machine. Probably VirtualBox? if you are using the default docker-machine on MacOS (boot2docker)

The problem is that your container that runs in a VM on your MacOS machine cannot necessarily talk to the same network as the one where your MacOS machine actually is (using 127.0.0.1 or localhost)

For example from my Mac:

$ ifconfig
...
vboxnet0: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:00
vboxnet1: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:01
vboxnet2: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:02
inet 192.168.99.1 netmask 0xffffff00 broadcast 192.168.99.255
vboxnet3: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:03
...

You see that the VirtualBox net vboxnet2 is the 192.168.99.x range. If you ssh into your docker-machine

$ docker-machine ssh default
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.8.1, build master : 7f12e95 - Thu Aug 13 03:24:56 UTC 2015
Docker version 1.8.1, build d12ea79
docker@default:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:2C:33:C7:80
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:2cff:fe33:c780/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1031 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1755 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:62290 (60.8 KiB)  TX bytes:2561234 (2.4 MiB)

eth0      Link encap:Ethernet  HWaddr 08:00:27:CC:FD:18
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fecc:fd18/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:482311 errors:0 dropped:0 overruns:0 frame:0
          TX packets:209033 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:401054787 (382.4 MiB)  TX bytes:12923400 (12.3 MiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:E6:C7:20
          inet addr:192.168.99.100  Bcast:192.168.99.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fee6:c720/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:47929 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47777 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3259250 (3.1 MiB)  TX bytes:10663711 (10.1 MiB)

You see that your container net is 172.17.x.x. So any container will belong to that network and it will not necessarily be able to route to another using 127.0.0.1 or localhost

Ok so there's a way you can access the mongodb on your host machine (MacOS) The docker container can see it through the vboxnet2 ip address 192.168.99.1 but the catch here is that mongodb has to bind to 0.0.0.0 (any IP) instead of 127.0.0.1. So if you look at the default mongodb running with meteor on your Mac.

 $ ps -Af | grep mongo
  503 75294 73105   0  6:08PM ttys005    0:00.00 grep mongo
  503 74375 74356   0  5:55PM ttys006    0:02.17 /Users/username/.meteor/packages/meteor-tool/.1.1.9.1sd3e7j++os.osx.x86_64+web.browser+web.cordova/mt-os.osx.x86_64/dev_bundle/mongodb/bin/mongod --bind_ip 127.0.0.1 --smallfiles --port 3001 --dbpath /Users/username/work/meteor/app/.meteor/local/db --oplogSize 8 --replSet meteor

you see that it's bound to IP 127.0.0.1 so when you try from your container:

user@b4d40a25f67d:/worker#:/worker# telnet 192.168.99.1 3001

you get no response.

The hack here is to just bind to 0.0.0.0 (not recommended for production):

~/.meteor/packages/meteor-tool/1.1.9/mt-os.osx.x86_64/tools/runners/run-mongo.js


-   '--bind_ip', '127.0.0.1', '--smallfiles', '--port', port, '--dbpath', dbPath,
+   '--bind_ip', '0.0.0.0', '--smallfiles', '--port', port, '--dbpath', dbPath,

Then voilá:

user@b4d40a25f67d:/worker# telnet 192.168.99.1 3001
Trying 192.168.99.1...
Connected to 192.168.99.1.
Escape character is '^]'.

Then, you need to modify this line in your worker.js

MongoClient.connect("mongodb://192.168.99.1:3001/meteor", function(err, db) {

And I'm happy to say that it works! :

$ docker run --rm -v "$(pwd)":/worker -w /worker iron/images:node-4.1 sh -c 'node worker.js'
Connected correctly to server

Upvotes: 5

Related Questions