apogiatzis / docker-compose-livereloader

A docker compose pattern to enable automatic container reloading.
77 stars 12 forks source link

Not working on Windows hosts. #6

Open patricknelson opened 4 years ago

patricknelson commented 4 years ago

I noticed that this wasn't working at all in Windows (see docker-compose.yml config below). When editing the file on the host machine, nothing happens, however if you manually update the file modification timestamp from within the container, it works fine, e.g.

# SSH into livereloader
docker-compose exec livereloader bash

# Manually update the file modification timestamp
touch /dev-sync/file.txt

I'm not a Python developer, but I believe this may have to do with how Python's Observer watches for changes. For example, my node.js containers work perfectly fine for file watching but for some reason this project's file watcher does not. Here's my docker-compose.yml.

version: '3'
services:
  proxy:
    container_name: proxy # Necessary for livereloader below.
    build: .
    ports: # host:container
      - "80:8080"
    restart: always
    volumes:
      - ./files:/dev-sync

  livereloader:
    container_name: livereloader
    image: apogiatzis/livereloading
    privileged: true
    environment:
      - RELOAD_DELAY=1.5
      - RELOAD_CONTAINER=proxy
      - RELOAD_DIR=/dev-sync/
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./files:/dev-sync

The details of my docker configuration are:

Docker version 19.03.1, build 74b1e89e8a
docker-machine version 0.16.1, build cce350d7 (i.e. Docker Toolbox)
VirtualBox 5.2.32
patricknelson commented 4 years ago

I did find a very hacky workaround that gets this to work on Windows here: http://blog.subjectify.us/miscellaneous/2017/04/24/docker-for-windows-watch-bindings.html

Basically, install python on the Windows host machine and then from the Windows command line:

:: Install package
pip install docker-windows-volume-watcher

:: Run volume watcher
docker-volume-watcher

But this has to run in parallel to Docker, so it has to be run every single time you docker-compose up. Unfortunately this isn't suitable for broad use for those of us running Windows, considering the extra layer of OS-specific complexity required (the whole point to using Docker). Would love to find a way to get this to work out of the box, similar to how node.js file watchers work (e.g. chokidar) which default to using file system events (e.g. inotify) but failover to less efficient methods for monitoring (e.g. recursion + looking at modification time).

RiverWalker92 commented 3 years ago

Had the same problem with vs code. @patricknelson you pointed me in the right direction with watchdog. After some investigation, the solution is remarkebly simple. Watchdog has another option for observer:

from watchdog.observers.polling import PollingObserver as Observer

Just replace the original observer with this one in reloader and it works like a charm! No docker-volume-watcher required. Which gives problems with wsl2 anyway.

https://github.com/gorakhargosh/watchdog/issues/283#issuecomment-61079649

patricknelson commented 3 years ago

Great idea @RiverWalker92. If you're up to it, submit a PR to this repo to add polling as an option (instead of inotify) configured via the docker-compose.yml environment variables. Then, you could set it up to default with the current functionality, but allow devs to configure that as an alternative in case they don't want to go through that workaround I suggested.

The workaround I suggested with docker-windows-volume-watcher is still superior to polling when you are working in projects with a large amount of files, so ideally there'd still be a fix for that (or just use that workaround), but this would be easier for folks in a time crunch or those with less files (thus polling is still efficient).

apogiatzis commented 3 years ago

Thanks for the PR @RiverWalker92 ! Just merged it. Should I keep this open for further discussion?