简体   繁体   中英

Nodemon doesn't reload in docker container when files change

I read many threads sabout this but no one solves anything.

Some say you have to add --legacy-watch (or -L ) to the nodemon command. Others shows several different configurations and apparently nodody really knows what you gotta do to achieve server restarting when a file change at the volume inside a docker container.

Here my configuration so far:

Dockerfile:

FROM node:latest

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# install nodemon globally
RUN npm install nodemon -g

# Install dependencies
COPY package*.json ./
RUN npm install

# Bundle app source
COPY . /usr/src/app

# Exports
EXPOSE 3000

CMD ["npm", "start"]

docker-compose.yml

version: '3.1'

services:
    node:
        build: .
        user: "node"
        volumes:
        - ./:/usr/src/app
        ports: 
            - 3000:3000
        depends_on: 
            - mongo
        working_dir: /usr/src/app
        environment:
        - NODE_ENV=production
        expose:
        - "3000"
    mongo:
        image: mongo
        expose:
        - 27017
        volumes:
        - ./data/db:/data/db
        environment:
            MONGO_INITDB_ROOT_USERNAME: root
            MONGO_INITDB_ROOT_PASSWORD: example

package.json

{
  "name": "node-playground",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon -L"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^2.7.1",
    "express": "^4.17.1",
    "mongoose": "^5.7.1"
  },
  "devDependencies": {
    "nodemon": "^1.19.2"
  }
}

I tried many different setups as well. Like not installing globally nodemon but only as a project dependency. And also running the command at the docker-compse.yml , and i believe many others I don't remember right now. Nothing.

If someone has any cetainty about this, please help. Thanks!!!!

Try it! This worked for me:

Via the CLI, use either --legacy-watch or -L for short. More informations here .

I went ahead and created an example container and repo to show how you can achieve this..

Just follow the steps below, which outline how to use nodemon inside of a Docker container.


Docker Container: at DockerHub

Source Code: at GitHub


package.json:

{
  "name": "nodemon-docker-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start:express": "node ./index.js",
    "start": "nodemon"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^1.19.2"
  }
}

Dockerfile:

FROM node:slim
WORKDIR /app
COPY package*.json ./
RUN apt-get update
RUN npm install
COPY . /app
# -or-
# COPY . .
EXPOSE 1337
CMD ["npm", "start"]

docker-compose.yml: (if you are using it)

version: "3"
services:
  nodemon-test:
    image: oze4/nodemon-docker-test
    ports:
      - "1337:1337"

How to reproduce:

Step 1 USING DOCKER RUN : SKIP IF YOU ARE USING DOCKER COMPOSE (go to step 1 below if you are) pull down example docker container

docker run -d --name "nodemon-test" -p 1337:1337 oze4/nodemon-docker-test

在此处输入图片说明


Step 1 USING DOCKER-COMPOSE :

See the docker-compose.yml file above for configuration

  1. cd /path/to/dir/that/has/your/compose/file
  2. docker-compose up -d

在此处输入图片说明


Step 2: verify the app works

http://localhost:1337

在此处输入图片说明


Step 3: check the container logs, to get a baseline

docker logs nodemon-test

在此处输入图片说明


Step 4: I have included a bash script to make editing a file as simple as possible. We need to pop a shell on the container, and run the bash script ( change.sh )

  1. docker exec -it nodemon-test /bin/bash

  2. bash change.sh

  3. exit

在此处输入图片说明


Step 5: check the logs again to verify changes were made and that nodemon restarted

docker logs nodemon-test

在此处输入图片说明



As you can see by the last screenshot, nodemon successfully restarted after changes were made!



All right Thanks a lot to MattOestreich for your answer.
Now i got it working, I don't know what it was, i did follow your set up but of course i'm using docker-compose and i also stripped some things out of it. I'm also not calling mongo image anymore since i setup the db in an Mongodb atlas cluster. my actual config: Dockerfile:

FROM node:12.10

WORKDIR /app

COPY package*.json ./

RUN apt-get update

RUN npm install

COPY . /app

EXPOSE 3000

CMD ["npm", "start"]

docker-compse.yml

version: '3.1'

services:
    node:
        build: .
        volumes:
        - ./:/app
        ports: 
            - 3000:3000
        working_dir: /app
        expose:
        - "3000"

package.json

{
  "name": "node-playground",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "dotenv": "^8.1.0",
    "ejs": "^2.7.1",
    "express": "^4.17.1",
    "mongoose": "^5.7.1"
  },
  "devDependencies": {
    "nodemon": "^1.19.2"
  }
}

thanks Matt again and i hope this thread helps people in need like me.

Nodemon depends on Chokidar and a potential solution is to make it use polling by setting CHOKIDAR_USEPOLLING environment variable to true .

For example you can do this in docker-compose.yml:

services: 
    api1:
        build: 
            context: .
            dockerfile: Dockerfile
        volumes:
            - /app/node_modules
            - ${PWD}:/app
        ports:
            - 80:3000
        environment:
            - CHOKIDAR_USEPOLLING=true

Change in Docker file

CMD ["npm", "start"]

Change start script

"start": "nodemon -L server.js"

Build Command

docker build . -t <containername>

Use this command to run the docker container

docker run -v $(pwd):/app -p 8080:8080 -it <container Id>
  • -v = Volumes . the preferred mechanism for persisting data generated by and used by Docker containers.
  • /app = WORKDIR /app
  • $(pwd) = PWD is a variable set to the present working directory. So $(pwd) gets the value of the present working directory

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