5

I am using watchdog to monitor a file directory for filesystem events. If this watcher script detects an event, I want to make an entry in a database (in this case Mongodb). The file system to be watched is actually a Docker volume linking its filesystem to my host pc's. All code is running in docker containers. I can attach to any of the containers in the system and use pymongo to correctly add an entry to the db.

I can also run the watcher on the host machine and all works as expected (including acting as expected if there is a change to the filesystem from the linked filesystem in a container.

However when I run the watcher code in a container, the methods in the event handler triggered by filesystem events never seems to be called. There are certainly no db entries created.

There are 3 sources of code:

  1. The watchdog directory 'watcher' including a watcher and a handler [watchdog_classes]

    import time
    from watchdog.observers import Observer
    import watchdog.events as events
    from data_persist import persistance_interface
    
    db_interface= persistance_interface()
    
    class RepoWatcher:
    
    
    
       def __init__(self, dir_root='/targer_dir/'):
            print(dir_root)
            self.observer = Observer()
            self.dir_root = dir_root
    
        def run(self):
            event_handler = CustomEventHandler()
            self.observer.schedule(event_handler, self.dir_root, recursive=True)
            self.observer.start()
            try:
                while True:
                    time.sleep(5)
            except KeyboardInterrupt:
                self.observer.stop()
                print("Shutting down...")
    
            self.observer.join()
    
    class CustomEventHandler(events.FileSystemEventHandler):
        @staticmethod
        def on_any_event(event):
    
            # Renamed files or dirs
            if isinstance(event, events.FileSystemMovedEvent):
                print("moved")
                db_interface.persist_one({'rename': 'renamed'})
    
            # Created files or dirs
            elif event.event_type == 'created':
                print("created")
                db_interface.persist_one({'create': 'creation'})
    
            # Deleted files or dirs
            elif isinstance(event, events.FileDeletedEvent):
                print("deleted")
                db_interface.persist_one({'deletion': 'deleted'})
    
  2. A class used to write to Mongodb [data_persist module]

    import pymongo
    from pymongo import MongoClient
    
    class persistance_interface():
        def __init__(self):
        self.client = MongoClient('db', 27017)
        self.db = self.client.filesystemeventsdb
        self.filesystemevents_collection = self.db.filesystemevents_collection
    
    def persist_one(self, data):
        self.asset_collection.insert_one(data)
    
  3. A script which triggers the watcher [watcher.py]

    import watchdog_classes
    
    watcher = watchdog_classes.RepoWatcher()
    watcher.run()
    

I am running the 3 code sources in the same Docker container, the mongodb is in another container.

The docker-compose.yaml looks like this:

version: '3'
services:

  db:
    image: tutum/mongodb
    ports:
      - "27017:27017"
    environment:
      - AUTH=no
    entrypoint: "usr/bin/mongod"

  sentry:
    build: ./Docker/sentry
    entrypoint: "python -u run_watcher.py"
    volumes:
      - "C:\\Users\\username\\Desktop\\HostVolume:/Container_Volume"

  web:
    build: ./Docker/site
    ports:
      - "8000:8000"
    command: python -u manage.py runserver 0.0.0.0:8000
    volumes:
      - "C:\\Users\\username\\Desktop\\HostVolume:/Container_Volume"

Why are the watchdog handler events not being called?

user3535074
  • 1,268
  • 8
  • 26
  • 48

1 Answers1

7

It seems that the source of my issue lied not within my code but Docker for windows does not notify container about any file changes you make from Windows. That means that only changes made to the volume from within the container are visible to it.

I found a workaround here, though it requires a that the host directory runs a script continuously. Not ideal but at least for not it works.

user3535074
  • 1,268
  • 8
  • 26
  • 48