Jak sprawić, by cargo watch/nodemon działały na kontenerach na Windows?

Problem

Pierwszym etapem było, sprawienie by projekt można było uruchomić możliwie szybko, by nie wymagało to instalacji od groma bibliotek i narzędzi. W najlepszym wypadku przystępując do pracy nad projektem, chciałbym musieć wpisać tylko jedno polecenie.  Pamiętałem też, że instalacja Redis na Windowsie jest problematyczna, a dostępne dystrybucje są przestarzałe. 

Mając powyższe na uwadze, stwierdziłem, że wybiorę Dockera. Wszystko to pokazuję w filmie https://youtu.be/U_RFCgpnbyY, gdzie prezentuję rozwiązanie dwóch problemów:

  • Zbyt dużych obrazów,
  • Zbyt wolnego tworzenia obrazów po każdej zmianie w trakcie developmentu.  

Co ciekawe, zdecydowałem, że problem zbyt wolnego budowania rozwiązywać będę na etapie budowania warstw obrazu. Rozdzielę ściąganie i budowanie zależności na dwie osobne warstwy. 

Alternatywne podejście

Moi wspaniali koledzy (Grzegorz Kowalik oraz Piotr Niewiejski) zapytali, czemu nie zamontuję katalogu Windowsowego i odpalę narzędzie, które będzie budowało i uruchamiało kod za każdym razem, gdy coś zmienię.

Szybko sprawdziłem ich pomysł. Plusy tego podejścia:

  • Buduję obraz tylko raz
  • Kompilacja i uruchamianie to odpowiedzialność uruchomionego kontenera
  • Mogę pracować z VS Code bez zauważenia zmiany.

Lekkie minusy:

  • Pierwsze uruchomienie jest najdłuższe

I teraz zaczyna się ciekawa zabawa 🙂 Odpaliłem kontener z odpowiednimi parametrami, w tym mount, by mieć dostępny w kontenerze katalog:

   docker run -it --mount type=bind,source="$(pwd)",target=/usr/src/arcology --name arcology-api-dev arcology-api-dev cargo-watch -x run

Wprowadzam pierwszą zmianę i nie działa. 

Myślałem, że to specyfika cargo watch, więc spróbowałem to samo z poziomu nodemona, ale bezskutecznie. 

Co ciekawe, po uruchomieniu shella wewnątrz kontenera zauważyłem, że zmiana pliku jest widoczna pomiędzy uruchomieniami nodemona. 

Odpalam nodemona => wprowadzam zmianę => brak reakcji => wyłączam nodemona => zmiana jest w pliku 🙂 

Jako że moja znajomość Linuxa jest mniejsza, niż bym potrzebował, poprosiłem mojego kolegę Piotrka Niewiejskiego o pomoc.

Przeszukując dokumentację, dowiedzieliśmy się, że zarówno Cargo Watch jak i Nodemon wykorzystują Inotify API, które są oparte na i-node, czyli dwóch bazowych mechanizmach z Linuxa. 

Na Linuxie działają bezproblemowo, bo są natywnymi mechanizmami. W moim przypadku to był Windows … 

Nasze pierwsze przypuszczenie, że notyfikacje z NTFS jakimś cudem nie dochodzą, okazały się prawidłowe. Uruchamiając kontener Dockerowy z poziomu shella Windowsowego oraz wykorzystując folder w systemie plików Windowsa, nie mogliśmy liczyć na to, że otrzymamy notyfikację o zmianie pliku, w wyniku czego zostanie przebudowany projekt przez cargo watch albo nodemona. 

Rozwiązanie

Na szczęście Piotrek bardzo szybko znalazł artykuł: https://levelup.gitconnected.com/docker-desktop-on-wsl2-the-problem-with-mixing-file-systems-a8b5dcd79b22, który pokazuje, że należy:

  • Należy mieć skonfigurowanego WSL 2.0. Tutaj jak to zrobić: https://docs.microsoft.com/en-us/windows/wsl/install-win10
  • Projekt powinien znaleźć się w systemie plików Linux, a nie Windows. Należy więc skopiować lub sklonować projekt wewnątrz obrazu Linuxa. Ja korzystam z Ubuntu 20-04, więc dla mnie root jest dostępny tu: \\wsl$\Ubuntu-20.04\
  • Włączyć integracje Dockera z dystrybucjami WSL 2.0. Tak WSL 2.0 jest tutaj wymagany.
  • Uruchomić kontener z wewnątrz Linux. Można na przykład wykorzystać do tego VS Code.
  • Jeśli zadziała to, w prawym dolnym rogu zobaczycie:
  • Można spokojnie odpalić kontener i developować:

    docker run -it -v ~/arcology:/usr/src/arcology --name arcology-api-dev arcology-api-dev cargo-watch -x run

Dla osoby, która słabo lub średnio ogarnia Linuxa, nie wie, jak działa Docker na Windowsie, nie wie czym się różni WSL 1.0 od WSL 2.0, może być to problem nie do przeskoczenia.  Dla mnie było to nie lada zaskoczenie.

Z tego miejsca dziękuję Piotrkowi za pomoc w rozwiązaniu problemu. Teraz wszystko śmiga i działa 🙂 

NodeStart - Twórz back-end w JavaScript / TypeScript
W dzień Senior Big Data Architect | Lead Developer | Software Developer w firmie Future Processing, w nocy śpi. Ponad 10 lat doświadczenia w zakresie wytwarzania oprogramowania w różnych technologiach oraz domenach, również w takich, w których nikt nie chciał pracować. Jak trzeba usunąć problem w dowolnej dziedzinie to wiesz do kogo dzwonić :) Zafascynowany rozwojem technologii związanej z przetwarzaniem danych a w szczególności tworzeniem rozwiązań z rodziny Big Data. Prelegent oraz organizator licznych wydarzeń, których głównym celem jest dzielenie się wiedzą oraz krzewienie potrzeby stosowania dobrych praktyk, w celu maksymalizacji jakości wytwarzanego produktu. Współorganizator Wakacyjnych Praktyk w Future Processing oraz prowadzący przedmiot na Politechnice Śląskiej „Tworzenie Oprogramowania w Zmiennym Środowisku Biznesowym”.
PODZIEL SIĘ