13

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!!!!

7
  • 1
    Are you calling nodemon in your NPM script? aka does npm start contain the nodemon command? Can you supply your package.json? I don't see where you are even running the nodemon command... Commented Sep 15, 2019 at 16:35
  • @MattOestreich so sorry, I forgot about that file. Edited. Commented Sep 15, 2019 at 17:27
  • You run the container as user node, while you also supply a volume that is owned by whatever user owns them in the host system. Are you sure you have the right permissions? Commented Sep 15, 2019 at 17:37
  • So is your container even starting? Is the app inside of your container responsive? Meaning, nodemon starts your app, it just doesn't reload when something changes? Commented Sep 15, 2019 at 17:56
  • @MichałSzydłowski I'll try removing the user reference. Commented Sep 15, 2019 at 18:10

5 Answers 5

33

Try it! This worked for me:

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

Sign up to request clarification or add additional context in comments.

4 Comments

Holy sh*t... my code was right! And I was just missing that flag.
Other packages have similar flags, for example npmjs.com/package/livereload has the "--usepolling" to activate this behavior. The underlying implementation that uses these flags is npmjs.com/package/chokidar
Firstly thanks, it worked for me, but it's too slow and the host doesn't reload the web tab itself, i have to do it manually. Is this a normal behavior, new in docker.
This still works in 2025
5

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

enter image description here


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

enter image description here


Step 2: verify the app works

http://localhost:1337

enter image description here


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

docker logs nodemon-test

enter image description here


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

enter image description here


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

docker logs nodemon-test

enter image description here



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



5 Comments

Uau thanks a lot for your instructions!! i'll tried them when i get back from work
One thought about your example is that I need to achive ths using docker-compose.
@MarcosDiPaolo my bad... I went ahead and added a step that outlines how to accomplish this using docker-compose... I also updated the GitHub Repo with the .yml file... Cheers!!
Is it necessary to change the files through docker exec ? Or can you normally code it throug VSCode and changes will be reflected?
Hi. Tks for the answer @MattOestreich. Can you outline what was the change you made that did it? I was comparing the equation files and what called my attention were the "node:slim" and the "apt-get" in Dockefile. Is any of those commands that made the difference?
4

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.

Comments

4

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

Comments

3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.