1

Situation:

I prototyped a small web (node.js) app and dockerized it for deployment and replicability purposes.

The app speaks with a MongoDB running directly on the host.

Problem:

On the server (AWS EC2 instance, only Port 80 and 443 open), I am not able to interact with MongoDB and I am wondering why.

docker run --net="host" -e 'NODE_ENV=production' -e 'MONGO_URI=mongodb://USER:PASSWORD!@172.31.32.1:27017/test_db' DOCKER_IMAGE
MongoDB connected ...
Warning: connect.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and will not scale past a single process.
HTTP Server started on port 80
(node:1) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
MongoNetworkError: failed to connect to server [172.31.32.1:27017] on first connect [MongoNetworkError: connection timed out
    at connectionFailureError (/app/server/node_modules/mongodb/lib/core/connection/connect.js:377:14)
    at Socket.<anonymous> (/app/server/node_modules/mongodb/lib/core/connection/connect.js:287:16)
    at Object.onceWrapper (events.js:284:20)
    at Socket.emit (events.js:196:13)
    at Socket._onTimeout (net.js:432:8)
    at listOnTimeout (internal/timers.js:531:17)
    at processTimers (internal/timers.js:475:7) {
  name: 'MongoNetworkError',
  [Symbol(mongoErrorContextSymbol)]: {}
}]
    at Pool.<anonymous> (/app/server/node_modules/mongodb/lib/core/topologies/server.js:433:11)
    at Pool.emit (events.js:196:13)
    at /app/server/node_modules/mongodb/lib/core/connection/pool.js:571:14
    at /app/server/node_modules/mongodb/lib/core/connection/pool.js:994:11
    at /app/server/node_modules/mongodb/lib/core/connection/connect.js:40:11
    at callback (/app/server/node_modules/mongodb/lib/core/connection/connect.js:262:5)
    at Socket.<anonymous> (/app/server/node_modules/mongodb/lib/core/connection/connect.js:287:7)
    at Object.onceWrapper (events.js:284:20)
    at Socket.emit (events.js:196:13)
    at Socket._onTimeout (net.js:432:8)
    at listOnTimeout (internal/timers.js:531:17)
    at processTimers (internal/timers.js:475:7) {
  name: 'MongoNetworkError',
  [Symbol(mongoErrorContextSymbol)]: {}
}

I initially tried localhost instead of the IP address, but that does not work. It throws an authentication error (which is somewhat strange). Since there is no host.docker.internal for Linux I had to (temporarily) resolve to the explicit IP address. The IP address that I am using I got via:

netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

What I find very strange is that I am not getting an Authentication error but a Timeout error, so to me it seems like the app is able to connect to Mongo. Also, the "MonogDB connected ..." would indicate that, as it is produced by the following line in my server script.

mongoose
    .connect(DB, { useNewUrlParser: true })
    .then(console.log("MongoDB connected ..."))
    .catch(err => console.log(err));

For completeness sake, the same setup (i.e. dockerized app and running MongoDB directly on the host) worked without a problem locally. Also, I am able to enter the Mongo Shell on the server via mongo.

Any explanation or tip is appreciated!

Fabian Bosler
  • 2,310
  • 2
  • 29
  • 49

1 Answers1

0

If mongo DB is running outside of the Docker, you can use the private IP of the EC2 instance to connect with Mongo DB (running on Host) from inside Docker.

EC2_PRIVATE_IP=$(curl http://169.254.169.254/latest/meta-data/local-ipv4)

docker run --net="host" -e 'NODE_ENV=production' -e 'MONGO_URI=mongodb://USER:PASSWORD!@$EC_PRIVATE_IP:27017/test_db' DOCKER_IMAGE
Adiii
  • 54,482
  • 7
  • 145
  • 148
  • 1
    that does not work, unfortunately. `MongoNetworkError: failed to connect to server [172.31.44.55:27017] on first connect [Error: connect ECONNREFUSED 172.31.44.55:27017 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1054:14) { name: 'MongoNetworkError', [Symbol(mongoErrorContextSymbol)]: {} }]` – Fabian Bosler Jan 07 '20 at 08:41
  • mongo DB running in the host? can you verify from terminal? – Adiii Jan 07 '20 at 08:53
  • 1
    @Adiii Jupp it is running in the host, verified by running `mongo -u USER -p PASSWORD` which logs into a mongo shell. By using the private IP is docker trying to connect to the instance from (for a lack of better words) "outside", which would then not work because port 27017 is not open by choice? – Fabian Bosler Jan 07 '20 at 09:03
  • using the public IP it will trying to connect from outside , not the private ip – Adiii Jan 07 '20 at 09:09
  • well, I did use the private IP. This is very annoying :D – Fabian Bosler Jan 07 '20 at 09:59