jamestheasiangenius
jamestheasiangenius

Reputation: 43

Can't connect to MongoDB container from other Docker container

I have two containers linked together by Docker compose and I can successfully ping the container containing MongoDB from the one containing my node.js app using the hostname. However, when it comes to actually connecting to the database, node.js tells me the connection is refused. I am using Docker for Mac if that helps.


    mongoose.connect("mongodb://mongo", {server: {auto_reconnect: true}}).catch(error => {
            console.log("DB CONNECTION ERROR");
            console.log(error)
        });


Here is my docker-compose.yml file:

    version: "3"

    services:
      mongo:
        image: mongo:latest
        volumes:
          - ./db:/data/db
        restart: always
        expose:
          - 27017
        ports:
          - 27017:27017
        container_name: mongo

      goose:
        depends_on:
          - mongo
        build: .
        volumes:
          - ./app/server/templates:/usr/src/app/app/server/templates
        expose:
          - 3005
        restart: always
        ports:
          - 3005:3005
        container_name: goose-compose

Upvotes: 3

Views: 6221

Answers (5)

Faical El Jabli
Faical El Jabli

Reputation: 11

Well i had a similar problem so all i had to do is creating a network in my docker-compose file

version: "3.7"

services:

  db:
    image: mongo:latest 
    restart: always
    container_name: db
    ports:
      - "27018:27018"
    environment:
      MONGO_INITDB_DATABASE: db 
    volumes:
      - db:/data/db
    networks: 
      - container-network

  app:
    image: scruc43r/app:dev
    build: 
      context: .
      target: dev
    container_name: app
    restart: always
    volumes: 
      - .:/app
    ports:
      - "5000:5000"
      - "3000:3000"
    depends_on:
      - db
    environment:
      - MONGODB_URI=mongodb://db/db
    networks: 
      - container-network


volumes: 
  db:
    name: db

networks: 
  container-network:
    name: container-network
    driver: bridge

in your config file you access the connection using

const Db_URI = process.env.MONGO_URI || "mongodb://localhost:27018/db"
const ConnectionOptions = {

    autoIndex: true,
    autoCreate: true,
    useNewUrlParser: true,
    useUnifiedTopology: true,
}

then in your main file you can connect

await mongoose.connect (Db_URI, ConnectionOptions)
.then(()=>{
console.log('DB Connectin Established Successfully');
})
.catch(err=>{
console.log(err);
})

Upvotes: 0

Alish Giri
Alish Giri

Reputation: 2238

Use this as your reference,

Dockerfile

FROM node:alpine
RUN mkdir -p /usr/src/app  # -p create all parent folders
WORKDIR /usr/src/app
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . .

docker-compose.yml

version: "3.8"

services:
  web:
    image: docker-node-mongo
    container_name: docker-node-mongo
    build: .  # path to your Dockerfile
    command: nodemon src/app.js # Use nodemon to reload on changes
    restart: always
    volumes:
      - ./src:/usr/src/app # To enable auto reload on changes
    ports:
      - "4000:4000"
    depends_on:
      - mongo_db

  mongo_db:
    image: mongo
    restart: always
    container_name: mongo_container # Use this in the connection url
    command: mongod -port 27017 --dbpath /data/db --replSet rs0
    ports:
      - "27017:27017"
    volumes:
      - mongo_storage:/data/db

volumes:
  mongo_storage:

Connection file

 const mongoose = require("mongoose")
 mongoose.connect("mongodb://mongo_container:27017/mongo-test?replicaSet=rs0", {
    useNewUrlParser: true,
    useCreateIndex: true,
 })

To enable replica set in mongodb,

docker compose up --build -d # to build your app in docker

docker exec -it mongo_db mongo # to enter in the mongo shell in docker

rs.initiate({ _id: "rs0", version: 1, members: [{ _id: 0, host : "mongo_db:27017" }] })

Upvotes: 1

jzakilla
jzakilla

Reputation: 7

I have a similarly built app using flask and mongodb in two separate containers. One difference that I notice between your compose and mine, is that you have volumes mentioned for each container, but no volume definition, like so:

version: "3"
services:
  web:
    image: jzakilla/bookfinderpy
    command: nginx -g "daemon off;"
    container_name: webapp
    ports:
      - 80:80
      - 443:443 # expose internal container ports to host
  db:
    image: mongo
    container_name: mongodb
    ports:
      - 27017:27017
    volumes:
      - book_db:/data/db
volumes:
  book_db:
    driver: local  

Without a volume section, and a driver to tell the container how to access the data I would imagine the container would spin up, but not actually be able to start the mongo service, thus giving you a denied error.

Upvotes: 0

Mayank Gupta
Mayank Gupta

Reputation: 2167

I was also facing the same issue with spring boot app and mongo db on windows. Try providing the mongo uri in Dockerfile in the format: data.mongodb.uri=mongodb://:27017/ under ENTRYPOINT.

Hope this helps.

Upvotes: 0

the0ffh
the0ffh

Reputation: 428

Expose ports without publishing them to the host machine - they’ll only be accessible to linked services. Only the internal port can be specified.

src: docker docs

If you want to take this approach, using bridge network mode (which is a default, as far as I remember) and expose, you have to use links, which will be deprecated very soon (or already are), or network (or networks - I don't remember correctly) property.

It is also worth to take a look at networking in compose part of docs.

[edit]
Btw, expose might even be omitted, since you are mapping containers' ports to host anyways (I think). Please do correct me with this one if I'm wrong.

Cheers.

Upvotes: 0

Related Questions