Search code examples
dockerdocker-composedockerfile

Connect localhost from mongo docker container , docker-compose


iam new into docker and docker-compose and i want to connect my locahost which runs on the local machine from docker-compose , i saw alot of examples and it connects me to mongodb but not the localhost so i cant find any of the data i want as u know 'with the way i use here , whenever the container goes down all the data is lost'

i mean how to Connect to 'mongodb://localhost:27017' Within a Docker Container

version: '3'

services:
  nest-app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: nest_cont1
    volumes:
      - .:/nest-app
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development


  mongo:
    image: mongo
    restart: always
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin111
      MONGO_INITDB_ROOT_PASSWORD: admin111

and here is my credentials

DB_USERNAME=admin111
DB_PASSWORD=admin111
DB_PORT=27017
DB_HOST=mongo

and thats docker file

FROM node:18
WORKDIR /nest-app
COPY package.json /nest-app
RUN npm install
COPY . /nest-app
EXPOSE 3000
CMD ["npm", "run", "start:dev"]

Solution

  • First, in order to persist data when the container goes down, you should use volumes. So you need to define a volume in your docker-compose.yml file and mount it at /data/db because that's where Mongo writes to by default (See DockerHub - MongoDB)

    Second, when you try to connect from one container to another you cannot use localhost because each container has it's own localhost meaning it would just try to connect to itself, and obviously you do not have an instance of MongoDB running inside your nest-app container.

    So to make that work you need to connect to the mongodb container. The good news is that's easy to do. Whenever you use container_name to assign a name to a container, Docker makes that name a DNS name which you can use to communicate with the container. So if your MongoDB container is called mongodb as in the example below you need to connect to mongodb://mongodb:27017 instead of mongodb://localhost:27017.

    Ideally, you should add a environment variable MONGODB_HOST or something along those lines which you then read from in your application and use that to build the connection string to MongoDB.

    You might also need to provide the username and password to authenticate to MongoDB.

    version: "3"
    
    services:
      nest-app:
        build:
          context: .
          dockerfile: Dockerfile
        container_name: nest_cont1
        volumes:
          - .:/nest-app
        ports:
          - "3000:3000"
        environment:
          NODE_ENV: development
          MONGODB_HOST: mongodb # must be container_name of the MongoDB container, adjust your application to use this environment variable to adjust
      mongo:
        image: mongo
        restart: always
        container_name: mongodb # this is the DNS name => so you need to connect to "mongodb://mongodb:27017" from within your application
        ports:
          - "27017:27017"
        volumes:
          - data-volume:/data/db # mount the volume, so the data is not lost
        environment:
          MONGO_INITDB_ROOT_USERNAME: admin111
          MONGO_INITDB_ROOT_PASSWORD: admin111
      # this is just a container to demonstrate that connection to MongoDB works, you can remove this as it's not required for the app to work
      # Access this Web UI at http://localhost:8081
      mongo-express:
        image: mongo-express
        ports:
          - "8081:8081"
        environment:
          ME_CONFIG_MONGODB_ADMINUSERNAME: admin111
          ME_CONFIG_MONGODB_ADMINPASSWORD: admin111
          ME_CONFIG_MONGODB_SERVER: mongodb # here again, we need to provide the hostname which is the container_name of the MongoDB container
    volumes:
      data-volume: # in this volume all the data will be saved when you stop/ delete the MongoDB container
    
    

    To verify it's working I've added node-express which is just a Web Client for MongoDB. You can access it at localhost:8081 and login with username admin and password pass and you should have access to the data within MongoDB. You can add a database or records here, then use docker compose down to stop the containers and then use docker compose up again to see that the data is being retained across container restarts.

    Here you can see that the connection is working:

    enter image description here