David Gatti
David Gatti

Reputation: 3701

NodeJS fs.watch is not reacting to changes inside a Docker Container

The idea of the following code is to react to changes in files inside a folder. When I run this code on my macOS everything works as executed.

let fs = require("fs");

let options = {
    encoding: 'buffer'
}

fs.watch('.', options, function(eventType, filename) {

    if(filename)
    {
        console.log(filename.toString());
    }

});

Inside a Docker Container on the other hand the code does not react to file changes. I run the code in the following way:

docker run -it --rm --name $(basename $(pwd)) -v $(pwd):/app -w /app node:slim sh -c 'node index'

Is there an option to use with Docker to allow system notifications for file changes?

Upvotes: 2

Views: 2696

Answers (1)

BlackStork
BlackStork

Reputation: 8331

New answer

Initially i advised Gulp (see bottom of the updated post with old answer). It did not worked because you tried to use it programatically, when Gulp is task runner and have own usage patterns, which i did not described. Since you need something specific, i have very simple, surely working solution for you.

It uses one of modules used by gulp called gaze - module which have approx 1.7m downloads per week. Its working, for sure on every system.

npm install gaze --save

To make it work lets create index.js in your root folder (which will be mounted to your app folder inside of the docker, and then just follow basic instruction given in module README:

 var gaze = require('gaze');

 // Watch all .js files/dirs in process.cwd() 
 gaze('**/*.js', function(err, watcher) {
 // Files have all started watching 
 // watcher === this 
 console.log('Watching files...');

 // Get all watched files 
 var watched = this.watched();

 // On file changed 
 this.on('changed', function(filepath) {
  console.log(filepath + ' was changed');
 });

 // On file added 
 this.on('added', function(filepath) {
   console.log(filepath + ' was added');
 });

  // On file deleted 
 this.on('deleted', function(filepath) {
  console.log(filepath + ' was deleted');
 });

 // On changed/added/deleted 
 this.on('all', function(event, filepath) {
  console.log(filepath + ' was ' + event);
 });

  // Get watched files with relative paths 
   var files = this.relative();
  });

Now lets run your command:

docker run -it --rm --name $(basename $(pwd)) -v $(pwd):/app -w /app node sh -c 'node index'

What we have upon changes - Linux outpud, but this works for Mac OS too.

   blackstork@linux-uksg:~/WebstormProjects/SO/case1> docker run -it --rm --name $(basename $(pwd)) -v $(pwd):/app -w /app node sh -c 'node index'
   Watching files...
   /app/bla was changed
   /app/foobar.js was changed

Old answer.

You can do it with gulp. Gulpfile.js

 const gulp = require('gulp');

 gulp.task( 'watch' , ()=>{
    return gulp.watch(['app/**'], ['doStuff']);
 });

 gulp.task( 'doStuff', cb => {
   console.log('stuff');
   //do stuff
   cb();
  });

So far such approach worked for me (of course you can build much more complex things, but if find using gulp conventient for different filesystem tasks).

Upvotes: 5

Related Questions