简体   繁体   中英

docker links not working with mongodb

Bit of a long issue. Been debugging this for nearly 2 days now and I think I might have finally found 2 possible issues.

what I'm trying to do is play with graphql, express and mongo using mongoose. Sounds simple enough? Having a few issues with connecting to the mongo server and asynchronous function and I believe it may have something to do with docker-compose links ?

Firstly my docker-compose structure that I'm playing with is pretty basic

version: "3"

services:
    db:
        build:
            context: '.docker/mongo'
        environment:
          - MONGODB_USER="root"
          - MONGODB_PASS="root"
        volumes:
          - ./.docker/mongo-data:/data/db
        ports:
            - 27017:27017

    node-cli:
        build:
            context: '.docker/pm2'
        working_dir: /var/www
        volumes:
            - ./:/var/www
        environment:
            - ENV=$ENV
            - KEYMETRICS_PUBLIC=$KEYMETRICS_PUBLIC
            - KEYMETRICS_SECRET=$KEYMETRICS_SECRET
        links:
            - db
        ports:
            - 3000:3000
    nginx:
        build:
            context: '.docker/nginx'
        ports:
            - 80:80
            - 43554:43554
            - 443:443
        environment:
           - NGINX_HOST=$NGINX_HOST
        links:
          - db
          - node-cli

You'll notice the containers are a 'node-cli' which is my express application running on keymetrics/pm2-docker-alpine:latest , there's a nginx which I'm not using at all at the moment; mentioning it now as it has some relevance as pm2 doesn't have a bash to ssh on.

My express app:

import express from 'express';
import graphqlHTTP from 'express-graphql';
import schema from './schema';

// const root = {
//     hello: 'heel',
//     users: {
//         id: 1,
//         firstname: 'test',
//         lastname: 'tester',
//     },
// };

const app = express();

app.use('/', graphqlHTTP({
    schema: schema,
    //rootValue: root,
    graphiql: true,
}));

app.listen(3000, () => console.log('Running server on 3000'));

My db file

import mongoose from 'mongoose';
import config from './config';

console.log('db config', config.config);

mongoose.connect(config.url, config.config, (error, db) => {

    if (error) {
        console.error('db error', error);
    } else {
        console.log('db success');
    }
});

mongoose.Promise = global.Promise;

const db = mongoose.connection;

export default db;

This all 'appears' to work find except the mongo connection. in the pm2 logs I can see MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017] . So there looks to be a connection issue? I installed mongodb on my host machine and ran mongo --host mongodb://localhost:27017/test and boom: connected fine. I then read something about ports so I checked the command running in the docker for mongodb which was mongod --bind_ip_all and checked I could connect to the database from my host using 127.0.0.1:27017 instead and worked fine!

I then wondered if the link for the docker was off, so I installed mongodb on the nginx container and tried to connect to the database and Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused so it appears there's an issue with connecting to the docker container from another container? I've built similar setups with mysql and php containers so I'm not sure why I can't connect to the mongo container from another container when the containers are linked?

Another possible issue I've witnessed could possibly be the async await functions however I've had no errors related to them other than the server hanging when requesting a resolve like below:

resolve: async (root, params, options, fieldASTs) => {
                    const projection = getProjection(fieldASTs);

                    console.log('select', projection);

                    console.log('before await');

                    const results = await userModel.find()
                        .select(projection)
                        .exec((error, result) => {
                            console.log('hello!');
                            console.log('error', error);
                            console.log('results', result);
                        });

                    console.log('success');

                    return results;
                },

In pm2 logs I get to before await and then after it just sits there hanging. Graphiql just sits there fetching. This could be because there's no database connection and I should really close/exit the process?

versioning:

pm2god: 2.5.0

mongo:

MongoDB shell version v3.6.0
git version: a57d8e71e6998a2d0afde7edc11bd23e5661c915
OpenSSL version: OpenSSL 1.0.1t  3 May 2016
allocator: tcmalloc
modules: none
build environment:
    distmod: debian81
    distarch: x86_64
    target_arch: x86_64

node: 8.1.3

packages:

{
  "name": "testgql",
  "version": "1.0.0",
  "main": "dist/index.js",
  "license": "MIT",
  "scripts": {
    "start": "webpack --config=webpack.config.js --progress --watch"
  },
  "dependencies": {
    "express": "^4.16.2",
    "express-graphql": "^0.6.11",
    "graphql": "^0.12.3",
    "mongoose": "^4.13.7"
  },
  "devDependencies": {
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.6.1",
    "webpack": "^3.10.0"
  }
}

mongo docker (latest from): https://hub.docker.com/_/mongo/

I've also just ran the application outside of the docker setup and it works perfect! Also connects to the database so it's definitely to do with docker containers not binding

You cannot use localhost from your node app to connect to your mongo container.

Check the docker-compose docs on how networking functions.

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

You need to use db:27017 from your node app.

The reason the connection works from your host is because you specified port mappings using ports .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM