My goal is to set up a Docker container that automatically restarts a NodeJS server when file changes are detected from the host machine.
I have chosen nodemon to watch the files for changes.
On Linux and Mac environments, nodemon and docker are working flawlessly.
However, when I am in a Windows environment, nodemon doesn't restart the server.
The files are updated on the host machine, and are linked using the volumes parameter in my docker-compose.yml file.
I can see the files have changed when I run docker exec <container-name> cat /path/to/fileChanged.js. This way I know the files are being linked correctly and have been modified in the container.
Is there any reason why nodemon doesn't restart the server for Windows?
Use nodemon --legacy-watch to poll for file changes instead of listening to file system events.
VirtualBox doesn't pass file system events over the vboxfs share to your Linux VM. If you're using Docker for Windows, it would appear HyperV doesn't propagate file system events either.
As a 2021 side note, Docker for Mac/Windows new GRPCfuse file system for mounting local files into the VM should send file system events across now.
2022 note: Looks like Windows/WSL Docker doesn't share FS events to the Linux VM (see comments #Mohamed Mirghani and #Ryan Wheale and github issue).
It is simple, according to the doc you must change:
nodemon server.js
to:
nodemon --legacy-watch server.js
As mentioned by others, using node --legacy-watch will work, however, the default polling rate is quite taxing on your cpu. In my case, it was consuming 30% of my CPU just by looping through all the files in my project. I would advise you to specify the polling interval as mention by #Sandokan El Cojo.
You can do so by either adding "pollingInterval": 4000 (4 seconds in this example) to your nodemon.json file or specifying it with the -P or --polling-interval flag in the command.
This was an issue in the docker for Windows. Now it's fixed
https://www.docker.com/blog/new-filesharing-implementation-in-docker-desktop-windows/
Related
I would like to use nodemon to restart my project when its files are changed. I think nodemon works by listening for inotify events to trigger reloading a node.js project.
The project runs in a docker container, and the project files are in a mounted volume.
When the project files are edited from inside the docker container, for example
docker-compose exec dev vim server.js
nodemon works correctly and restarts the server.
However, when an editor running on the host machine is used, nodemon does not pick up the changes and restart the program.
The contents of the files in the docker container do in fact change, so I suspect editing files this way just doesn't trigger an FS event.
Is it possible to set this up so that editing files on the host machine causes file system events to occur in the Docker container? Why does this not happen already?
Platform Info:
Docker for Windows (Hyper-V)
node docker container
WebStorm -- Host based editor
It looks like file system events just don't work when Docker is running in Hyper-V and the changes happen on the host. But, it's possible to work around that limitation by enabling polling in nodemon:
nodemon -L server.js
In WebStorm the full command that ends up getting used is
docker-compose run dev node node_packages/nodemon/bin/nodemon.js -L server.js
More info:
https://github.com/remy/nodemon#application-isnt-restarting
I need some help with nodemone and webpack. My team and I are working on a project, we are still in the early stage, but I've been fighting this issue for three days.
We are working on a remote physical host that runs multiple VMs. Each VM is serving different purpose. I have setup an NFS share between the VM and the host. We all work from home so we upload the files via FTP to the host (actually we use Visual Studio Code with ftp-sync plugin, so when I hit the save button, the file automatically uploads to the remote folder). However, nodemon and webpack are not detecting the change in the file.
I have mounted the nfs share with the following options:
mount -o noac,sync <host IP address>:/path/to/folder
I have checked the ctime and mtime and they are in perfect sync. However, for some reason the change in the file is never detected by webpack and nodemon. If I hit touch within the guest, it works.
Can anyone suggest any solution to this issue?
I actually managed to find a solution literally few minutes after I posted my answer. So basically the issue was fixed by adding "--watch-poll" argument to my package.json scripts.
"scripts": {
"dev:build": "webpack -w --watch-poll",
"dev": "cross-env NODE_ENV=development nodemon dist/index.bundle.js" }
Right now, when I save the file within Visual Studio Code, it is automatically uploaded to the host, synced with the VM development environment and automatically re-compiled and the server restarted with nodemon.
I'm trying to work on a dev environment with Node.js and Docker.
I want to be able to:
run my docker container when I boot my computer once and for all;
make changes in my local source code and see the changes without interacting with the docker container (with a mount).
I've tried the Node image and, if I understand correctly, it is not what I'm looking for.
I know how to make the mount point, but I'm missing how the server is supposed to detect the changes and "relaunch" itself.
I'm new to Node.js so if there is a better way to do things, feel free to share.
run my docker container when I boot my computer once and for all;
start containers automatically with the docker daemon or with your process manager
make changes in my local source code and see the changes without
interacting with the docker container (with a mount).
You need to mount your dev app folder as a volume
$ docker run --name myapp -v /app/src:/app image/app
and set in your Dockerfile nodeJs
CMD ["nodemon", "-L", "/app"]
Are there any workable approaches to watch/reload within docker?
The use case here is development, where switching between branches may change one or more of backend, frontend or database provisioning files.
Example: I have a node.js application. If server JS code changes, I want the backend server to restart. If package.json changes, I want the "install" container (runs npm install, saving node_modules to a shared Volume). If SQL files change, I want the provisioning container to run its psql commands again.
Basically, I want to watch certain files and restart the process if they change (container itself is not technically restarted). Supervisord isn't cut out for watching, but seems like process managers like PM2 or Forever would normally be the slam dunk choice if it weren't for the docker consideration.
I have just gotten a VPS to bring my first node.js project online, but I am wondering where do I place the node files like app.js if I want it to be accessible at http://www.mywebsite.com:3000?
Right now, to host a website, I am using WHM to create a cPanel account, which creates /home/cpanelusername and my HTML/PHP files all go into /home/cpanelusername/public_html. Where does node.js files go to? Or did I get this step wrong as well?
On my Mac where I developed the node app, I simply cd into the directory containing the node file and run node app.js
You have to execute app.js file using the node binary, just like you do in local development. That means that you should probably make that execution a service call, the details of which depend on your linux distro. If it's not a service call, then executing it in ssh will mean that the app stops working once you log out of ssh.
For example, in Ubuntu server (which I use) I have an Upstart script which automatically runs my node.js app automatically on system start and log to /var/log. An example of the file, named /etc/init/myapp.js.conf is:
description "myapp server"
author "Me"
# used to be: start on startup
# until we found some mounts weren't ready yet while booting:
start on started mountall
stop on shutdown
script
# We found $HOME is needed. Without it we ran into problems
export HOME="/root"
exec node /home/me/myapp/myapp.js 2>&1 >> /var/log/myapp.log
end script
Replace names, etc. as necessary.
Edit to add: You can then start and stop your service by running:
sudo start myapp.js or sudo stop myapp.js