Changing the source code does not live update using docker-compose and volumes on mern stack - node.js

I would like to implement a hot reloading functionality from development evinronement such that when i change anything in the source code it will reflect the changes up to the docker container by mounting the volume and hence see the changes live in my localhost.
Below is my docker-compose file
version: '3.9'
services:
server:
restart: always
build:
context: ./server
dockerfile: Dockerfile
volumes:
# don't overwrite this folder in container with the local one
- ./app/node_modules
# map current local directory to the /app inside the container
#This is a must for development in order to update our container whenever a change to the source code is made. Without this, you would have to rebuild the image each time you make a change to source code.
- ./server:/app
# ports:
# - 3001:3001
depends_on:
- mongodb
environment:
NODE_ENV: ${NODE_ENV}
MONGO_URI: mongodb://${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD}#mongodb
networks:
- anfel-network
client:
stdin_open: true
build:
context: ./client
dockerfile: Dockerfile
volumes:
- ./app/node_modules
- ./client:/app
# ports:
# - 3000:3000
depends_on:
- server
networks:
- anfel-network
mongodb:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
volumes:
# for persistence storage
- mongodb-data:/data/db
networks:
- anfel-network
# mongo express used during development
mongo-express:
image: mongo-express
depends_on:
- mongodb
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_ROOT_USERNAME}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_ROOT_PASSWORD}
ME_CONFIG_MONGODB_PORT: 27017
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_BASICAUTH_USERNAME: root
ME_CONFIG_BASICAUTH_PASSWORD: root
volumes:
- mongodb-data
networks:
- anfel-network
nginx:
restart: always
depends_on:
- server
- client
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- '8080:80'
networks:
- anfel-network
# volumes:
# - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
anfel-network:
driver: bridge
volumes:
mongodb-data:
driver: local
Any suggestions would be appreciated.

You have to create a bind mount, this can help you

Related

Docker/ Traefik: Cannot route services to the host provided

I'm new to traefik, and I can't figure why my configuration do not work as expected.
Here is the context :
2 front-end app, builded and copy/pasted into a nginx folder using Dockerfile
1 rest api, compiled and running with node using Dockerfile
1 postgres database and pgadmin
1 mongo database and mongo-express.
All of this is setup in a docker-compose.
Frontend Dockerfile:
FROM node:lts-alpine as build
WORKDIR /app/frontend-app1 -- frontend-app2 for the other
COPY package*.json ./
RUN npm install
COPY . ./
RUN npm run build
FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/frontend-app1/build /usr/share/nginx/html/frontend-app1
EXPOSE 3001 -- 3002 from frontend-app2
CMD ["nginx", "-g", "daemon off;"]
API Dockerfile:
FROM node:14-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
ARG NODE_ENV=qual
ENV NODE_ENV=${NODE_ENV}
EXPOSE 3000
CMD ["node", "dist/main"]
Docker-compose:
version: "3.8"
networks:
backend-network:
traefik-network:
name: traefik-network
external: true
services:
mongo:
container_name: wow_mongo
image: mongo
restart: always
ports:
- 27017:27017
networks:
- backend-network
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: xxx
MONGO_INITDB_DATABASE: xxx
MONGO_INITDB_USERNAME: xxx
MONGO_INITDB_PASSWORD: xxx
volumes:
- ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh
mongo-express:
container_name: wow_mongo_express
image: mongo-express
depends_on:
- mongo
restart: always
ports:
- 8081:8081
networks:
- traefik-network
- backend-network
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: xxx
ME_CONFIG_MONGODB_ADMINPASSWORD: xxx
ME_CONFIG_MONGODB_URL: mongodb://xxx:xxx#mongo:27017/
labels:
- "traefik.enable=true"
- "traefik.http.routers.mongo-express.rule=Host(`me-qual.xxx.com`)"
- "traefik.http.routers.mongo-express.entrypoints=web"
postgres:
container_name: wow_postgres
image: postgres
restart: always
ports:
- 5432:5432
networks:
- backend-network
environment:
POSTGRES_PASSWORD: xxx
POSTGRES_USER: xxx
POSTGRES_DB: xxx
pgadmin:
container_name: wow_pgadmin
image: dpage/pgadmin4
depends_on:
- postgres
restart: always
networks:
- traefik-network
- backend-network
ports:
- 5050:80
environment:
PGADMIN_DEFAULT_EMAIL: xxx
PGADMIN_DEFAULT_PASSWORD: xxx
labels:
- "traefik.enable=true"
- "traefik.http.routers.pgadmin.rule=Host(`pgadmin-qual.xxx.com`)"
- "traefik.http.routers.pgadmin.entrypoints=web"
- "traefik.docker.network=traefik-network"
traefik:
container_name: wow_traefik
image: traefik:v2.6
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/traefik-conf/traefik.yml:/etc/traefik/traefik.yml
- $PWD/traefik-conf/acme.json:/letsencrypt/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`traefik.xxx.com`)"
- "traefik.http.routers.api.service=api#internal"
- "traefik.http.routers.api.entrypoints=web"
- "traefik.http.routers.api.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=xxx:xxx"
# - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
# - "traefik.http.middlewares.strip-www.redirectregex.regex=^https?://(www\\.)(.+)"
# - "traefik.http.middlewares.strip-www.redirectregex.replacement=https://$${2}"
# - "traefik.http.middlewares.strip-www.redirectregex.permanent=true"
api:
container_name: wow_api
depends_on:
- postgres
- mongo
restart: unless-stopped
image: wow_api:1.0.0
build:
context: ../wow-api
dockerfile: Dockerfile
ports:
- 3000:3000
networks:
- traefik-network
- backend-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wow-api.rule=Host(`api-qual.xxx.com`)"
- "traefik.http.routers.wow-api.entryPoints=web"
admin:
container_name: wow_admin
# depends_on:
# - api
restart: always
image: wow_admin:1.0.0
build:
context: ../wow-admin
dockerfile: Dockerfile
ports:
- 3002:80
networks:
- traefik-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wow-admin.rule=Host(`admin-qual.xxx.com`, `www.admin-qual.xxx.com`)"
- "traefik.http.routers.wow-admin.entrypoints=web"
# - "traefik.http.routers.blog.middlewares=strip-www"
# - "traefik.http.routers.blog.tls=true"
# - "traefik.http.routers.blog.tls.certresolver=letsencrypt"
consultant:
container_name: wow_consultant
# depends_on:
# - api
restart: always
image: wow_consultant:1.0.0
build:
context: ../wow-consultant
dockerfile: Dockerfile
ports:
- 3001:80
networks:
- traefik-network
labels:
- "traefik.enable=true"
- "traefik.http.routers.wow-consultant.rule=Host(`consultant-qual.xxx.com`, `www.admin-qual.xxx.com`)"
- "traefik.http.routers.wow-consultant.entrypoints=web"
And my traefik config is simple since I can't manage to make it work without tls.
global:
sendAnonymousUsage: false
log:
level: "INFO"
format: "common"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: true
swarmMode: false
watch: true
network: traefik-network
api:
dashboard: true
entryPoints:
web:
address: ":80"
# http:
# redirections:
# entryPoint:
# to: "websecure"
# scheme: "https"
# permanent: true
websecure:
address: ":443"
# http:
# tls:
# certResolver: "letsencrypt"
# certificatesResolvers:
# letsencrypt:
# acme:
# email: "xxx"
# storage: "/letsencrypt/acme.json"
# tlsChallenge: {}
I figure out to make traefik.my_domain.com to work and to log using basic auth.
I can also navigate throught my differents services using localhost:<PORT_BINDED>
But as soon as I want to reach, for example, a front end app, I get a Gateway timeout and can't manage to make it work if I don't specify the port.
For example, accessing to the frontend app which is related to the consultant service:
consulltant-qual.xxx.com result in a gateway timeout, but if I ask consulltant-qual.xxx.com:3001, I can access to my app.
Any help would be grateful,
Thanks

Docker-compose - Nodejs can not find Mongo service when bind mount

Here is my docker-compose.yml, when I comment the volumes code of "khaothi-manager" my services work correctly. But when uncomment it, my Node service throw an error that it can not connect to Mongo
version: "3.8"
services:
mongo:
image: mongo
restart: always
env_file: ./.env
ports:
- $MONGO_LOCAL_PORT:$DB_PORT
volumes:
- ./data:/data/db
networks:
- hm_khaothi
khaothi-manager:
container_name: khaothi-manager
image: khaothi-manager
restart: always
volumes:
- ./admin:/app
build: ./admin
env_file: ./.env
links:
- mongo
- khaothi-resource
ports:
- $MANAGER_PORT:$MANAGER_PORT
environment:
- MANAGER_HOST=$MANAGER_HOST
- MANAGER_PORT=$MANAGER_PORT
- RESOURCE_HOST=khaothi-resource
- RESOURCE_PORT:$RESOURCE_PORT
- DB_HOST=mongo
- DB_NAME=$DB_NAME
- DB_PORT=$DB_PORT
networks:
- hm_khaothi
My Dockerfile
# syntax=docker/dockerfile:1
FROM node:14-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]
This is the error
(node:37) UnhandledPromiseRejectionWarning: MongooseServerSelectionError: connection timed out
at NativeConnection.Connection.openUri (/app/node_modules/mongoose/lib/connection.js:807:32)
at /app/node_modules/mongoose/lib/index.js:342:10
...
It worked correctly when I add another volume /app/node_modules
khaothi-manager:
container_name: khaothi-manager
image: khaothi-manager
restart: always
volumes:
- ./admin:/app
- /app/node_modules

Can't get docker-compose networking to work

I'm trying to make requests to my server container from my client app in another container. The Docker Compose docs state that the network is setup automatically, so shouldn't all ports be accessible from all containers? When I make a curl request to port 4000 from outside of the container (in a fresh terminal), it works. However when I enter the client container (selektor-client) and try the same request, it fails.
curl --request POST http://localhost:4000/api/music
What am I doing wrong?
docker-compose.yaml:
version: "3"
services:
client:
container_name: selektor-client
restart: always
build: ./client
ports:
- "3000:3000"
volumes:
- ./client/:/client/
- /client/node_modules/
command: ["yarn", "start"]
server:
container_name: selektor-server
restart: always
build: ./server
ports:
- "4000:4000"
volumes:
- ./server/:/server/
depends_on:
- mongo
command: ["yarn", "start"]
mongo:
container_name: selektor-mongo
command: mongod --noauth
build: .
restart: always
volumes:
# - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- data-volume:/data/db
ports:
- "27017:27017"
volumes:
data-volume:
When you call containers of the same stack each other, the host name is, by default, the service name, and the port is the internal port: <servicename>:<internal_port>. So, based on this part of your example:
version: "3"
server:
container_name: selektor-server
restart: always
build: ./server
ports:
- "4000:4000"
volumes:
- ./server/:/server/
depends_on:
- mongo
command: ["yarn", "start"]
The url you client have to use to reach the server is http://server:4000
I had the same problem . my solution was registering network and giving subnet mast to the network and register the static ip to each container :
version: "3"
networks:
my_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
services:
mongodb:
image: mongo:4.2.1
container_name: mongo
command: mongod --auth
hostname: mongo
networks:
my_network:
ipv4_address: 172.20.0.5
volumes:
- /data/db/mongo:/data/db
ports:
- "27017:27017"
rabitmq:
hostname: rabbitmq
container_name: rabbitmq
image: rabbitmq:latest
networks:
my_network:
ipv4_address: 172.20.0.3
volumes:
- /var/lib/rabbitmq:/data/db
ports:
- "5672:5672"
- "15672:15672"
restart: always
you can access through IP addresses

Docker compose error to connect postgres database with Node API

I am having the connection error with the docker-composer when I try to access a postgres database through an API in Node.
I'm using Sequelize as ORM to acess the database. But I'dont know what happened.
docker-compose.yml:
version: '3.5'
services:
api-service:
build:
context: .
dockerfile: ./api-docker.dockerfile
image: api-service
container_name: api-service
restart: always
env_file: .env
environment:
- NODE_ENV=$NODE_ENV
ports:
- ${PORT}:3000
volumes:
- .:/home/node/api
- node_modules:/home/node/api/node_modules
depends_on:
- postgres-db
networks:
- api-network
command: npm run start:dev
postgres-db:
expose:
- ${PORT_SERVICE}
ports:
- ${PORT_SERVICE}:5432
restart: always
env_file: .env
volumes:
- pgReportData:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${USER_SERVICE}
POSTGRES_PASSWORD: ${PASSWORD_SERVICE}
POSTGRES_DB: ${DATABASE_SERVICE}
networks:
- api-network
container_name: postgres-db
image: postgres:10
networks:
api-network:
driver: bridge
volumes:
pgReportData:
driver: local
node_modules:
.env:
NODE_ENV=development
PORT=30780
HOST_SERVICE=postgres-db
DATABASE_SERVICE=base
USER_SERVICE=user
PASSWORD_SERVICE=password
DIALECT=postgres
PORT_SERVICE=5444
api-docker.dockerfile:
FROM node:12
WORKDIR /src
COPY . .
COPY --chown=node:node . .
USER node
RUN npm install
EXPOSE $PORT
ENTRYPOINT ["npm", "run", "start:dev"]
And when I run:
docker-compose up
I'm getting this error:
Any ideia?
Can someone help me ??
If node is the only app that connects to postgre-db you can remove the networks, and expose the postgredb running port (5432). To connect to the db you can simply use the container name as host.
Connection String: "postgres://YourUserName:YourPassword#postgres-db:5432/YourDatabase";
version: '3.5'
services:
api-service:
build:
context: .
dockerfile: ./api-docker.dockerfile
image: api-service
container_name: api-service
restart: always
env_file: .env
environment:
- NODE_ENV=$NODE_ENV
ports:
- ${PORT}:3000
volumes:
- .:/home/node/api
- node_modules:/home/node/api/node_modules
depends_on:
- postgres-db
command: npm run start:dev
postgres-db:
expose:
- 5432
restart: always
env_file: .env
volumes:
- pgReportData:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${USER_SERVICE}
POSTGRES_PASSWORD: ${PASSWORD_SERVICE}
POSTGRES_DB: ${DATABASE_SERVICE}
container_name: postgres-db
image: postgres:10
volumes:
pgReportData:
driver: local
node_modules:

Docker compose build error

If I use command docker-compose build, I'll get error that looks like:
ERROR: Validation failed in file './docker-compose.yml', reason(s):
Service 'php' configuration key 'expose' '0' is invalid: should be of
the format 'PORT[/PROTOCOL]'
I use the last version docker and docker-compose.
My docker-compose.yml has the next code:
application:
build: code
volumes:
- ./symfony:/var/www/symfony
- ./logs/symfony:/var/www/symfony/app/logs
tty: true
db:
image: mysql
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: symfony
MYSQL_USER: root
MYSQL_PASSWORD: root
php:
build: php-fpm
expose:
- 9000:9000
volumes_from:
- application
links:
- db
nginx:
build: nginx
ports:
- 80:80
links:
- php
volumes_from:
- application
volumes:
- ./logs/nginx/:/var/log/nginx
elk:
image: willdurand/elk
ports:
- 81:80
volumes:
- ./elk/logstash:/etc/logstash
- ./elk/logstash/patterns:/opt/logstash/patterns
volumes_from:
- application
- php
- nginx
I use an ubuntu 14.04
Could you tell me how is fix it?
You need to put the port definitions in quotes for short ports (2 digits). This is a result of the nature of YAML and the used parser in docker-compose.
application:
build: code
volumes:
- ./symfony:/var/www/symfony
- ./logs/symfony:/var/www/symfony/app/logs
tty: true
db:
image: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: symfony
MYSQL_USER: root
MYSQL_PASSWORD: root
php:
build: php-fpm
expose:
- "9000"
volumes_from:
- application
links:
- db
nginx:
build: nginx
ports:
- "80:80"
links:
- php
volumes_from:
- application
volumes:
- ./logs/nginx/:/var/log/nginx
elk:
image: willdurand/elk
ports:
- "81:80"
volumes:
- ./elk/logstash:/etc/logstash
- ./elk/logstash/patterns:/opt/logstash/patterns
volumes_from:
- application
- php
- nginx
Also the expose statement should come with a single number only and also be quoted.
Added all needed changes in the above.

Resources