skip to Main Content

I have nestjs application with prisma mongodb setup. Nestjs connects well to dockerized mongo while running itself (nestjs) outside docker.

But when I try to run nestjs inside docker, it can’t connect to mongo.

docker-compose.yml

version: '3.8'

# For connection urls to the following instances, see
# https://github.com/prisma/prisma/blob/main/TESTING.md#environment-variables
services:
  # Replica Set (required for Prisma Client)
  mongo:
    container_name: mongo
    build:
      dockerfile: ./docker/mongo.Dockerfile
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: prisma
      MONGO_REPLICA_HOST: 127.0.0.1
      MONGO_REPLICA_PORT: 27018
    env_file:
      - .env
    ports:
      - '27018:27018'
  web:
    build:
      dockerfile: ./docker/app.Dockerfile
    environment:
      DATABASE_URL: mongodb://root:prisma@mongo:27018/bookmeon?authSource=admin
    env_file:
      - .env
    ports:
      - '1337:1337'
    depends_on:
      - mongo

mongo.Dockerfile:

###################
# MONGO container - for replication
###################

FROM mongo:4 As mongo

# we take over the default & start mongo in replica set mode in a background task
ENTRYPOINT mongod --port $MONGO_REPLICA_PORT --replSet rs0 --bind_ip 0.0.0.0 & MONGOD_PID=$!; 
# we prepare the replica set with a single node and prepare the root user config
INIT_REPL_CMD="rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: '$MONGO_REPLICA_HOST:$MONGO_REPLICA_PORT' }] })"; 
INIT_USER_CMD="db.getUser('$MONGO_INITDB_ROOT_USERNAME') || db.createUser({ user: '$MONGO_INITDB_ROOT_USERNAME', pwd: '$MONGO_INITDB_ROOT_PASSWORD', roles: [ 'root' ] })"; 
# we wait for the replica set to be ready and then submit the commands just above
until (mongo admin --port $MONGO_REPLICA_PORT --eval "$INIT_REPL_CMD && $INIT_USER_CMD"); do sleep 1; done; 
# we are done but we keep the container by waiting on signals from the mongo task
echo "REPLICA SET ONLINE"; wait $MONGOD_PID;

app.Dockerfile:

###################
# base
###################

#FROM node:20.5.1-alpine3.18 As base
FROM node:20.5.1-alpine3.18 As base
RUN apk add openssl1.1-compat
RUN apk add musl

RUN npm i -g pnpm

###################
# deps install
###################

FROM base As deps

WORKDIR /my

COPY --chown=node:node ./package.json .

RUN pnpm i

###################
# build
###################

FROM base As build

WORKDIR /my

COPY --chown=node:node --from=deps ./my/. .
COPY --chown=node:node ./tsconfig* .
COPY --chown=node:node ./webpack.js .

COPY --chown=node:node ./prisma ./prisma
COPY --chown=node:node ./src ./src
COPY --chown=node:node ./aps ./aps

ARG DATABASE_URL="mongodb://root:prisma@mongo:27018/bookmeon?authSource=admin"

RUN pnpm exec prisma generate
RUN pnpm run build

USER node

CMD [ "node", "dist/main.js" ]

.env:

DATABASE_URL="mongodb://root:prisma@mongo:27018/bookmeon?authSource=admin"

MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=prisma
MONGO_REPLICA_HOST=127.0.0.1
MONGO_REPLICA_PORT=27018

NODE_ENV=staging
FORCE_WWW=0
FORCE_TLS=0

Error i get in dockerized nestjs:

book_me_on-web-1  | PrismaClientInitializationError: Raw query failed. Code: `unknown`. Message: `Server selection timeout: No available servers. Topology: { Type: ReplicaSetNoPrimary, Servers: [ { Address: 127.0.0.1:27018, Type: Unknown, Error: Connection refused (os error 111) }, ] }`
book_me_on-web-1  |     at r (/my/node_modules/.pnpm/@[email protected][email protected]/node_modules/@prisma/client/runtime/library.js:103:2766)
book_me_on-web-1  |     at async Proxy.onModuleInit (/my/dist/prisma.service.js:14:9)
book_me_on-web-1  |     at async Promise.all (index 0)
book_me_on-web-1  |     at async callModuleInitHook (/my/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected][email protected][email protected]/node_modules/@nestjs/core/hooks/on-module-init.hook.js:43:5)
book_me_on-web-1  |     at async NestApplication.callInitHook (/my/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected][email protected][email protected]/node_modules/@nestjs/core/nest-application-context.js:223:13)
book_me_on-web-1  |     at async NestApplication.init (/my/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected][email protected][email protected]/node_modules/@nestjs/core/nest-application.js:97:9)
book_me_on-web-1  |     at async NestApplication.listen (/my/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected][email protected][email protected]/node_modules/@nestjs/core/nest-application.js:166:33)
book_me_on-web-1  |     at async bootstrap (/my/dist/main.js:21:5) {
book_me_on-web-1  |   clientVersion: '5.0.0',
book_me_on-web-1  |   errorCode: 'P2010'
book_me_on-web-1  | }
book_me_on-web-1  | 
book_me_on-web-1  | Node.js v20.5.1

UPDATE:

I tried to create small docker container which logs some runtime envs (and changed MONGO_REPLICA_HOST to 172.19.0.2 manually);

FROM node:20.5.1-alpine3.18 as base

# ping $MONGO_REPLICA_HOST:$MONGO_REPLICA_PORT; 

ENTRYPOINT echo $NODE_ENV; 
sleep 5s & PID=$!; 
echo $MONGO_REPLICA_PORT; 
echo $MONGO_REPLICA_HOST; 
ping "mongo":$MONGO_REPLICA_PORT; 
echo "Done"; 
echo "Process ID" + PID;

As a result in resulting log i see that nestjs tries to connect to
172.19.0.2:27018, while in this new test container I see that mongo is pinged by 172.19.0.3:27018 (using mongo host name)

web      | PrismaClientInitializationError: Raw query failed. Code: `unknown`. Message: `Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: 172.19.0.2:27018, Type: Unknown, Error: Connection refused (os error 111) }, ] }`

So looks like mongo runs on a bit another ip address than I start it and nestjs tries to connect to wrong place in docker.

2

Answers


  1. Chosen as BEST ANSWER

    I was sure that it's something with prisma client generation IP address substitution, but turned out it was my docker daemon. I have completely reinstalled docker daemon (removed all images/containers as well) and reinstalled all images, recreated containers again.

    And with no changes in dockerfiles, dockercompose or prisma scheme nestjs starts well now. Thanks to everyone!


  2. When running within Docker, your localhost (127.0.0.1) is not visible to Docker network – you need to set your env variable MONGO_REPLICA_HOST to mongo (the name of the service you have defined in your docker-compose), that way Docker will understand which service you are pointing to and will automatically set the host value

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search