We have been using single container Docker images for some time without issues on RHEL8. We need to move toward integrating multiple services using docker-compose but have not been successful in even simple attempts.
We are using Mongo (mongo:4.2.3-bionic) and NodeJS (node:alpine).
We created a simple node application which is trying to add a single document to a MongoDB collection. The code for dbwrite.js is:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://mongo:27017/", function(err, mongodb) {
if (err) throw err;
var mongodbo = mongodb.db("test");
var doc = {"payload":"test doc"};
mongodbo.collection("test2").insertOne(doc, function(err, res) {
if (err) throw err;
});
mongodb.close();
});
The Dockerfile for dbwrite.js is:
FROM node:alpine
ADD . /
CMD ["node", "dbwrite.js"]
The Mongo container was pulled from DockerHub as was the Node container.
The docker-compose.yaml file:
version: '3.1'
services:
mongo:
image: mongo:4.2.3-bionic
container_name: mongo
restart: always
ports:
- 27017:27017
volumes:
- ./mongo_db:/data/db
app:
image: dbwrite:v0.1
container_name: dbwrite
If we perform "docker-compose up" the dbwrite container throws an error:
dbwrite | /node_modules/mongodb/lib/topologies/server.js:233
dbwrite | throw err;
dbwrite | ^
dbwrite |
dbwrite | MongoNetworkError: failed to connect to server [mongo:27017] on first connect [Error: connect EHOSTUNREACH 172.22.0.2:27017
dbwrite | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1137:16) {
dbwrite | name: 'MongoNetworkError',
dbwrite | [Symbol(mongoErrorContextSymbol)]: {}
dbwrite | }]
dbwrite | at Pool.<anonymous> (/node_modules/mongodb/lib/core/topologies/server.js:438:11)
dbwrite | at Pool.emit (events.js:321:20)
dbwrite | at /node_modules/mongodb/lib/core/connection/pool.js:561:14
dbwrite | at /node_modules/mongodb/lib/core/connection/pool.js:994:11
dbwrite | at /node_modules/mongodb/lib/core/connection/connect.js:31:7
dbwrite | at callback (/node_modules/mongodb/lib/core/connection/connect.js:264:5)
dbwrite | at Socket.<anonymous> (/node_modules/mongodb/lib/core/connection/connect.js:294:7)
dbwrite | at Object.onceWrapper (events.js:428:26)
dbwrite | at Socket.emit (events.js:321:20)
dbwrite | at emitErrorNT (internal/streams/destroy.js:84:8) {
dbwrite | name: 'MongoNetworkError',
dbwrite | [Symbol(mongoErrorContextSymbol)]: {}
dbwrite | }
dbwrite exited with code 1
Rebuilding the container (doing it the hard way -- I know -- but wanting to keep everything as identical as possible), and replacing the Dockerfile CMD line
CMD ["node", "dbwrite.js"]
with
CMD ["ping", "-c", "20", "mongo"]
yields normal ping responses from "mongo" so I believe the default network was created right and the DNS is happening as expected, yet my node application gets EHOSTUNREACH.
dbwrite | 64 bytes from 172.22.0.2: seq=15 ttl=64 time=0.072 ms
dbwrite | 64 bytes from 172.22.0.2: seq=16 ttl=64 time=0.080 ms
dbwrite | 64 bytes from 172.22.0.2: seq=17 ttl=64 time=0.067 ms
dbwrite | 64 bytes from 172.22.0.2: seq=18 ttl=64 time=0.121 ms
dbwrite | 64 bytes from 172.22.0.2: seq=19 ttl=64 time=0.097 ms
dbwrite |
dbwrite | --- mongo ping statistics ---
dbwrite | 20 packets transmitted, 20 packets received, 0% packet loss
dbwrite | round-trip min/avg/max = 0.065/0.086/0.121 ms
dbwrite exited with code 0
If we edit the dbwrite.js code and replace, "mongo" in the connect() method with "localhost" and execute "node dbwrite.js" from the localhost (outside a container), the Document to the Collection. The Mongo container log reports that it is listening on 0.0.0.0.
mongo | 2020-02-10T19:35:26.337+0000 I NETWORK [listener] Listening on 0.0.0.0
mongo | 2020-02-10T19:35:26.337+0000 I NETWORK [listener] waiting for connections on port 27017
While I don't have the output captured, previous executions of "docker network inspect" showed both containers and their assigned IPv4 addresses on 172.22.0.x/16. IPAM showed using the default driver "bridge" on subnet 172.22.0.0/16 and a gateway of 172.22.0.1.
Any suggestions on what could be wrong would be greatly appreciated. We are on the verge of down-grading off RHEL8 to see if that is related to our problem given that Red Hat so vocally claims NOT to support Docker. Seems like it is some network security issue since ICMP ping can traverse the bridge but TCP socket connection cannot.