Repository navigation
[BUG] Compose Watch With “node –watch” Only Reloads First Time #11090
Description
Activity
+1, experienced this exact scenario with my local project too.
is there any way to help move forward with this?
I can reproduce this scenario, investigating...
Seems to me this is a
node --watchbug/limitation, see my reproduction example:- run the illustration example container (
docker build -t t . && docker run --rm -it -p 8000:8000 t) - in another terminal, docker exec inside container
- copy file to a temporary name
cp src/index.mjs test.mjs - edit test.mjs to change message
cp test.mjs src/index.mjs- node show "Restarting 'src/index.mjs'"- edit test.mjs again
cp test.mjs src/index.mjs- node doesn't detect changes
AFAICT the reason for this is that after a
cp(or compose watch sync) the monitored file is rewritten and get a new inode assigned. I assume node watch monitors file by inode, and then don't get any new file event detected. The initial sync works as the file is overridden (inode is deleted)- run the illustration example container (
Interesting... what do you propose?
I need to check the same applies to a plain Linux hosts, then if confirmed, this issue should be reported to nodeJS.
The other option would require to design an alternative approach forcompose watchto sync files.Reacted by Moshe BrevdaI can't reproduce file inode change when running on a plain Linux VM. I wonder this issue could be a side effect for overlay filesystem used by container, but unclear to me
I used
straceto check how doing acpinside container is implemented at system level:execve("/bin/cp", ["cp", "test", "src/index.mjs"], 0xffffcfdaefa0 /* 9 vars */) = 0 set_tid_address(0xffffabefde58) = 18 brk(NULL) = 0xaaaaf3c9a000 brk(0xaaaaf3c9c000) = 0xaaaaf3c9c000 mmap(0xaaaaf3c9a000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xaaaaf3c9a000 mprotect(0xaaaad462c000, 16384, PROT_READ) = 0 getuid() = 0 newfstatat(AT_FDCWD, "test", {st_mode=S_IFREG|0644, st_size=189, ...}, 0) = 0 newfstatat(AT_FDCWD, "src/index.mjs", {st_mode=S_IFREG|0644, st_size=189, ...}, 0) = 0 newfstatat(AT_FDCWD, "test", {st_mode=S_IFREG|0644, st_size=189, ...}, 0) = 0 newfstatat(AT_FDCWD, "src/index.mjs", {st_mode=S_IFREG|0644, st_size=189, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(AT_FDCWD, "test", O_RDONLY|O_LARGEFILE) = 3 openat(AT_FDCWD, "src/index.mjs", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0100644) = -1 EEXIST (File exists) unlinkat(AT_FDCWD, "src/index.mjs", 0) = 0 openat(AT_FDCWD, "src/index.mjs", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0100644) = 4 sendfile(4, 3, NULL, 16777216) = 189 sendfile(4, 3, NULL, 16777216) = 0 close(4) = 0 close(3) = 0 exit_group(0) = ?Note the
unlinkatthenopenatcalls withO_CREAT, which basically means file is recreated. Seems to confirm my assumption overlayfs used for container layering doesn't work well with inotify, which expect a fixed inode for monitored file.As this issue is not specific to Docker Compose I created moby/moby#47061 and will close this one. If some workaround is suggested there we can apply to compose, we obviously would adopt it.
Thanks for looking into this. Can you explain why the first change is detected?
unlinkat(file delete) triggers an inotify event, then nodejs reload the file (which has been recreated in the meantime)ah! Makes sense. Thanks! 🙏 🙏
Node issue: nodejs/node#51621
Reacted by Paul Ohlhauser
Description
I am trying to use compose watch to get a node server to reload on change using "node --watch"
Current Behaviour:
Server correctly reloads on first change. On subsequent changes, the logs show the file has been synced and I can see the file in the container is updated, but the server does not reload.
Expected Behaviour
Server correctly reloads on all changes.
Steps To Reproduce
Compose Version
Docker Environment
Anything else?
The link below goes directly to the part of the video where I demonstrate this issue.
https://youtu.be/HkLR26VY07c?t=675