NestJS does not connect with MongoDB when using Docker containers - node.js

NestJS App connect normally with MongoDB
but, after creating a docker containers for them
NestJS does not connect with MongoDB
here's Dockerfile
# Base image
FROM node:16-alpine
# Create app directory
WORKDIR /app
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./
# Install app dependencies
RUN yarn install
# Bundle app source
COPY . .
# Creates a "dist" folder with the production build
RUN yarn build
here's the docker compose file
version: '3.8'
services:
mongodb:
image: mongo:latest
env_file:
- .env
ports:
- 27017:27017
volumes:
- mongodb_data_container:/data/db
api:
build: .
volumes:
- .:/app
- /app/node_modules
ports:
- ${PORT}:${PORT}
command: npm run start:dev
env_file:
- .env
depends_on:
- mongodb
volumes:
mongodb_data_container:
here's .env file
PORT=3000
DB_CONNECTION_STRING=mongodb://127.0.0.1:27017/db-name
here's the connect method inside NestJS app
MongooseModule.forRoot(process.env.DB_CONNECTION_STRING)

For everyone facing the same issue
replace mongodb://127.0.0.1:27017/db-name
with mongodb://mongodb:27017/db-name

Related

Why my docker-compose volume doesn't detect changement

I'm learning docker & docker-compose i have a vueJS App and a nestjs api that i try to dockerize
what i want to do is to setup volume so when i'll change something in the file i don't have to rebuild again this is what i did:
Docker-compose.yml (in a different directory)
services:
front:
build: ../ecommerce-front # I tried to add :/app but my container doesn't find app/package.json
ports:
- "8080:8080"
volumes:
- ../ecommerce-front/src
back:
build: ../ecommerce-back
ports:
- "3000:3000"
depends_on:
- mysql
volumes:
- ../ecommerce-back/src
mysql:
image: mysql:5.7
ports:
- 3306:3306
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: tools
MYSQL_PASSWORD: root
backend Dockerfile:
FROM node:14 AS builder
WORKDIR /app
COPY ./package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:10-alpine
WORKDIR /app
COPY --from=builder /app ./
CMD ["npm", "run", "start:dev"]
i have no error, my services is running well but when i make some changes to my back there's no changement in the container
What did i do wrong ?
Thanks by advance
Thanks to richardsefton it seems i needed to add node_modules as volume to my two services like this:
volumes:
- ../ecommerce-front:/app
- '/app/node_modules'
volumes:
- ../ecommerce-back:/app
- '/app/node_modules'

Nodemon not restarting in docker image

I am very new to docker and trying to get a working environment for local development. My issue is I can't seem to get nodemon to trigger correctly when there are changes. The nodemon config works outside of docker so I know that isn't the issue.
Here is what I have in my node app folder.
# Dockerfile.local
FROM node:16
WORKDIR /app
COPY package*.json .
RUN yarn install
COPY . .
RUN yarn build
CMD ["yarn", "watch"]
# docker-compose.yml
version: "3"
services:
db:
image: postgres:12.3
restart: always
volumes:
- db_data:/var/lib/postgresql/data
environment:
# ... my config
actions:
build:
context: ./action-handlers
dockerfile: .docker/${DOCKERFILE}
depends_on:
- "hasura"
volumes:
- actions:/./app
environment:
# ...my confg
hasura:
ports:
- 8080:8080
- 9691:9691
build:
context: ./hasura
dockerfile: .docker/${DOCKERFILE}
depends_on:
- "db"
environment:
# ...my config
volumes:
db_data:
actions:
The docker image works perfectly when I run docker-compose build to build the image, then to run it using docker-compose up. Nodemon runs, the other two services run as expect so there isn't any issues there. It just doesn't restart when I make code changes. I have a feeling I am not using volumes correctly.
I have a feeling that - "./actions:/app/action-handers" is incorrect.

Install all needed node modules inside Docker container, not just copying them

The problem is the following. We have a project with several services running with docker compose.
When one of us adds a new module with npm install <module name> --save, the package*.json files are going to be updated and the module is going to be installed in the node_module folder.
Here, running docker-compose up --build everything works fine.
Nevertheless, when someone else pulls the updated versions of the package*.json files and tries to run docker-compose up --build Docker outputs the error that the module is not found.
It seems like the local node_module folder is copied directly into the Docker container.
The question is how can we make it possible that all needed node modules which are in the package*.json files are going to be installed inside the container not just copied?
Here is one DOCKERFILE:
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD npm run devStart
as well as the docker-compose.yaml file:
version: "3"
services:
list-service:
build:
context: ./list-service
dockerfile: Dockerfile
ports:
- "4041"
volumes:
- ./list_service:/usr/src/app
#- /usr/src/app/node_modules
user-service:
build:
context: ./user_service
dockerfile: Dockerfile
ports:
- "4040"
volumes:
- ./user_service:/usr/src/app
# - /usr/src/app/node_modules
api-gateway:
build:
context: ./api_gateway
dockerfile: Dockerfile
ports:
- "5000:5000"
volumes:
- ./api_gateway:/usr/src/app
# - /usr/src/app/node_modules
date_list-service:
build:
context: ./date_list_service
dockerfile: Dockerfile
ports:
- "4042"
volumes:
- ./date_list_service:/usr/src/app
# - /usr/src/app/node_modules
mongo:
container_name: mongo
image: mongo
command: mongod --port 27018
volumes:
- data:/data/db
volumes:
data:
We do have already a .dockerignore file:
node_modules
npm-debug.log
Update
#DazWilkin recognized that we mount our context into the container. This overrides the images content with local content. We do this because we use nodemon. Therefore, we can see changes in the code on the fly. Is there a possibility to exclude the node_modules directory from this?
I think that your issue is that Docker is caching layers and not detecting the changed package*.json.
What happens if everyone docker-compose up --build --no-cache?
NOTE because you're running npm install in the container image build, you don't need (and probably don't want) to npm install on the host beforehand
NOTE Since you're using containers, you may want to use a container registry too. That way, once the first updated docker images have been built, everyone else can pull these from the registry rather than rebuild them for themselves.
Update
I just noticed that you're mounting your context in container; you don't want to do that. It will override the work you've done building the container:
version: "3"
services:
list-service:
build:
context: ./list-service
dockerfile: Dockerfile
ports:
- "4041"
volumes:
- ./list_service:/usr/src/app <<< ---- DELETE
#- /usr/src/app/node_modules
user-service:
build:
context: ./user_service
dockerfile: Dockerfile
ports:
- "4040"
volumes:
- ./user_service:/usr/src/app <<< ---- DELETE
# - /usr/src/app/node_modules
api-gateway:
build:
context: ./api_gateway
dockerfile: Dockerfile
ports:
- "5000:5000"
volumes:
- ./api_gateway:/usr/src/app <<< ---- DELETE
# - /usr/src/app/node_modules
date_list-service:
build:
context: ./date_list_service
dockerfile: Dockerfile
ports:
- "4042"
volumes:
- ./date_list_service:/usr/src/app <<< ---- DELETE
# - /usr/src/app/node_modules
mongo:
container_name: mongo
image: mongo
command: mongod --port 27018
volumes:
- data:/data/db
volumes:
data:

Environment variables not loading inside docker container

I have two services which are dockerized. The first service is the api service which depends on the mongo service. However, for some reason, the api service can't connect to the mongo service because the environment variables inside the container are not been passed around well. I have two variables in my .env namely
JWT_SECRET=somesecret
DB_URL_LOCAL=mongodb://mongo:27017/apii
I tried setting the environment variables in the docker-compose file, when I run docker-compose config I see the variables and their values displayed, but my application can't detect these variables. MongoDB keeps throwing UnhandledPromiseRejectionWarning: MongoParseError: URI malformed, cannot be parsed error.
I also tried to set the environment variables in the main Dockerfile but it still didn't work. Please I need some assistance. Here is a copy of my Dockerfile and docker-compose.yml file.
This is the Dockerfile
FROM node:12-alpine AS base
WORKDIR /usr/src/app
FROM base AS build
COPY package*.json .babelrc ./
RUN npm install
COPY ./src ./src
RUN npm run build
RUN npm prune --production
FROM base AS release
COPY --from=build /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/dist ./dist
USER node
EXPOSE 4000
CMD [ "node", "./dist/server/server.js" ]
This is the docker-compose.yml file
version: '3.8'
services:
api:
build: .
image: api
working_dir: /usr/src/app
expose:
- 4000
ports:
- '4000:4000'
depends_on:
- mongo
mongo:
container_name: mongo
env_file:
- .env
environment:
- DB_URL_LOCAL=$DB_URL_LOCAL
- JWT_SECRET=$JWT_SECRET
image: mongo
volumes:
- './data:/data/db'
ports:
- 27017:27017
restart: always
Thank you.
In docker-compose.yml, environment variables should be declared in api service not mongo service with something like this MONGO_INITDB_DATABASE=${DATABASE}
Use this, env_file is an alternative, read more:
version: '3.8'
services:
api:
build: .
image: api
working_dir: /usr/src/app
expose:
- 4000
ports:
- '4000:4000'
env_file:
- ./secret.env
environment:
- DB_URL_LOCAL=${DB_URL_LOCAL}
- JWT_SECRET=${JWT_SECRET}
depends_on:
- mongo
mongo:
container_name: mongo
image: mongo
volumes:
- './data:/data/db'
ports:
- 27017:27017
restart: always

How to use sqlite3 with docker compose

Between the following tutorials;
Dockerizing create-react-app
Developing microservices - Node, react & docker
I have been able to convert my nodejs app to dockerized micro-services which is up and running and connecting to services. However, my app uses Sqlite/Sequelize and this was working perfectly prior to dockerizing.
With the new setup, I get error;
/usr/src/app/node_modules/sequelize/lib/dialects/sqlite/connection-manager.js:31
throw new Error('Please install sqlite3 package manually');
Error: Please install sqlite3 package manually at new ConnectionManager
(/usr/src/app/node_modules/sequelize/lib/dialects/sqlite/connection-manager.js:31:15)
My question is;
Is it possible to use Sqlite3 with Docker
If so, anyone able to share sample docker-compose.yml and Dockerfile combo that works for this please.
My docker-compose.yml
version: '3.5'
services:
user-service:
container_name: user-service
build: ./services/user/
volumes:
- './services/user:/usr/src/app'
- './services/user/package.json:/usr/src/package.json'
ports:
- '9000:9000' # expose ports - HOST:CONTAINER
web-service:
container_name: web-service
build:
context: ./services/web
dockerfile: Dockerfile
volumes:
- './services/web:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- '3000:3000' # expose ports - HOST:CONTAINER
environment:
- NODE_ENV=development
depends_on:
- user-service
My user/ Dockerfile
FROM node:latest
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
ADD package.json /usr/src/package.json
RUN npm install
# start app
CMD ["npm", "start"]
My web/ Dockerfile
FROM node:latest
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts#1.1.4
RUN npm install gulp -g
# start app
CMD ["npm", "start"]
Many thanks.
Got it. The issue was that my local node_modules were being copied to the host container. Hence in the sqlite3 lib/binding, node-v57-darwin-x64 was there instead of what is expected - node-v57-linux-x64. Hence the mess.
I updated the Dockerfiles and docker-compose.yml as follows:
My docker-compose.yml
services:
user-service:
container_name: user-service
build:
context: ./services/user/
dockerfile: Dockerfile
volumes:
- './services/user:/usr/src/app'
- '/usr/src/node_modules'
ports:
- '9000:9000' # expose ports - HOST:CONTAINER
web-service:
container_name: web-service
build:
context: ./services/web/
dockerfile: Dockerfile
volumes:
- './services/web:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- '3000:3000' # expose ports - HOST:CONTAINER
environment:
- NODE_ENV=development
depends_on:
- user-service
My user/ Dockerfile
FROM node:latest
# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# add `/usr/src/node_modules/.bin` to $PATH
ENV PATH /usr/src/node_modules/.bin:$PATH
# install and cache app dependencies
ADD package.json /usr/src/package.json
RUN npm install
# start app
CMD ["npm", "start"]
Helpful posts
Getting npm packages to be installed with docker-compose

Resources