简体   繁体   中英

Docker Nodemon not reloading on changes even though -L is set

Hi I'm trying to dockerize an app im currently working on. It uses nodejs and mariadb. I have some difficulties with figuring out how to make nodemon work.

I tried using --legacy-watch or -L which is the short form but it didn't change the result.

NPM installs all dependecies correct i even get the nodemon text but it doesn't restart the server when i make changes.

Would be gal if anyone could help

package.json:

{
  "name": "nodejs_mariadb_docker_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node src/index.js",
    "dev": "nodemon -L src/index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.2",
    "mariadb": "^2.5.5",
    "nodemon": "^2.0.15"
  }
}

Dockerfile for nodejs:

# Specifies the image of your engine
FROM node:16.13.2

# The working directory inside your container
WORKDIR /app

# Get the package.json first to install dependencies
COPY package.json /app

# This will install those dependencies
RUN npm install

# Copy the rest of the app to the working directory
COPY . /app

# Run the container
CMD ["npm", "run", "dev"]

and the docker compose file:

version: "3"
services: 
  node:
    build: .
    container_name: express-api
    ports:
      - "80:8000"
    depends_on: 
      - mysql

  mysql:
    image: mariadb:latest
    ports:
      - "3306:3306"
    environment: 
      MYSQL_ROOT_PASSWORD: "password"
    volumes:
      - mysqldata:/var/lib/mysql
      - ./mysql-dump:/docker-entrypoint-initdb.d
volumes:
    mysqldata: {}

Having the same Dockerfile be used for development and for a final self-contained image is hard. During development you want the container to react to changes you make on the host file system. For the final image you want it to be self-contained and have the code inside the image.

A thing you can do is to have a Dockerfile with 2 different ways to build the image and then use the target specification on the build in your docker-compose file to point to the kind of image you want.

If you change your Dockerfile to have both kinds of images like this

# Specifies the image of your engine. Label it as 'development' for use in the docker-compose file
FROM node:16.13.2 as development
# The working directory inside your container
WORKDIR /app
# When starting in development, we install packages and then run nodemon
RUN ["/bin/sh", "-c", "npm install && npm run dev"]

# This is the part of the Dockerfile that's used when we build the final image
# Specifies the image of your engine
FROM node:16.13.2 as final
# The working directory inside your container
WORKDIR /app
# Get the package.json first to install dependencies
COPY package.json /app
# This will install those dependencies
RUN npm install
# Copy the rest of the app to the working directory
COPY . /app
# Run the container
CMD ["npm", "run", "start"]

Then you can change your docker-compose file to map the current directory to /app and to ask for the 'development' version of the image like this

version: "3"
services: 
  node:
    build: 
      context: .
      target: development
    container_name: express-api
    volumes:
      - .:/app
    ports:
      - "80:8000"
    depends_on: 
      - mysql

  mysql:
    image: mariadb:latest
    ports:
      - "3306:3306"
    environment: 
      MYSQL_ROOT_PASSWORD: "password"
    volumes:
      - mysqldata:/var/lib/mysql
      - ./mysql-dump:/docker-entrypoint-initdb.d
volumes:
    mysqldata: {}

Now you should be able to change files on the host file system and have the container pick them up.

When you're done and you want to create the final, self-contained image, you change the docker-compose file to the same as it is now (I've only shown the part of the file for the node image. The database part is the same as before).

version: "3"
services: 
  node:
    build: .
    container_name: express-api
    ports:
      - "80:8000"
    depends_on: 
      - mysql

Now there's no 'target', so docker-compose will run through the whole Dockerfile and build the 'final' version of the image. Everything in the 'development' part of the Dockerfile will be run when you build the image, but it won't affect the final image at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM