watchdog.observers.Observer works in Windows, works in docker on Linux, does not work in docker on Windows
Docker Windows Volume Watcher
It is also possible to use Docker Windows Volume Watcher. The Python script monitors folder bindings of Docker containers hosted on Windows and updates those containers with file changes.
Install using pip
(supports Python 2 & 3).
pip install docker-windows-volume-watcher
Monitor all directory bindings of all containers.
docker-volume-watcher
Monitor only bindings of container container_name.
docker-volume-watcher container_name
Monitor only binding of container_name to host directory C:\some\directory.
docker-volume-watcher container_name C:\some\directory
Limitations
- The script doesn't propagate to container file deletion events.
- The script requires stat and chmod utils to be installed in container.
https://forums.docker.com/t/file-system-watch-does-not-work-with-mounted-volumes/12038/9 http://blog.subjectify.us/miscellaneous/2017/04/24/docker-for-windows-watch-bindings.html
watchdog and PollingObserver()
Another solution is to use the class PollingObserver
.
But it is significantly slower if the watchdog has to monitor multiple files and folders with one schedule.
import sys
import time
import logging
from watchdog.observers.polling import PollingObserver
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
event_handler = LoggingEventHandler()
observer = PollingObserver()
# Limit the number of files by setup multiple schedule
observer.schedule(event_handler, '/folder/subfolder') # All files in a subfolder
observer.schedule(event_handler, '/folder/file') # A file
observer.schedule(event_handler, '/folder/file2') # A file
# etc...
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
The underlying API that watchdog uses to monitor linux filesystem events is called inotify. The Docker for Windows WSL 2 backend documentation notes:
Linux containers only receive file change events (“inotify events”) if the original files are stored in the Linux filesystem.
The directory you're mounting, c:\My_MR
, resides on the Windows file system and thus inotify inside the watcher container doesn't work.
Instead, you can run docker from inside your WSL 2 default distribution with a linux filesystem path, e.g., ~/my_mr
:
docker run -d --network onprem_network -v ~/my_mr:/code/My_MR --name watcher watcher
docker run -d --network onprem_network -v ~/my_mr:/code/My_MR --name parser parser
This directory can be accessed from Windows while that WSL 2 distribution is running using the \\wsl$\
network path, i.e., \\wsl$\<Distro name>\home\<username>\my_mr
(more info here). Accordingly, I believe docker run
could also be used from Windows using the \\wsl$\
path with -v
.