Archiwa tagu: docker-for-mac

Mutagen – synchronizacja plików z Dockerem i nie tylko

W codziennej pracy, programiści pracując na dużej ilości plików chcą mieć do nich bezpośredni i szybki dostęp, a efekt zmian w kodzie powinien być widoczny bez zbędnych i dodatkowych działań. Po drodze spotykamy wiele blokad związanych z konfiguracją, zastosowaną technologią, używanym systemem operacyjnym lub źródłem danych.

Przykłady?

– pracujesz nad dużym projektem PHP w środowisku Dockera na OSX – okazuje się, że montowanie twoich lokalnych plików drastycznie spowalnia działanie aplikacji, a uruchomienie composer install trwa wieczność.

– jesteś zmuszony do wykonania bezpośredniej akcji na plikach znajdujących się na serwerze. Praca przez SSH okazuje się uciążliwa i marzysz o tym, żeby móc pracować na tych plikach lokalnie – w swoim IDE.

– rozpoczynasz pracę nad zdockeryzowaną aplikacją (np. fluentbit, elasticsearch, solr), której konfiguracja zaszyta jest w obrazie. Zamiast tworzyć pliki konfiguracyjne lokalnie i odpowiednio je montować, wolałbyś mieć do nich bezpośredni dostęp „na żywo”.

– pracujesz lokalnie na Ubuntu, a twoja aplikacja uruchomiona jest w Dockerze, z podmontowanymi katalogami. Okazuje się, że aplikacja ma problemy z uprawnieniami do plików i katalogów lub je zmienia, a to tylko początek problemów.

Mutagen

Takie problemy (uproszczone na potrzeby artykułu) można mnożyć bez końca, ale jak sobie z nimi radzić? Z pomocą przychodzi nam jedno narzędzie – Mutagen (https://mutagen.io/).

Mutagen jest narzędziem open-source umożliwiającym proste, wielostronne, w pełni konfigurowalne i błyskawiczne synchronizowanie plików. W porównaniu z podobnymi narzędziami używanymi dotychczas (np. Unison, docker-sync) charakteryzuje się wysoką wydajnością, stabilnością, prostotą użycia, wieloplatformowością oraz aktywnym wsparciem ze strony twórców.

Ogólne działanie sprowadza się do uruchomienia sesji synchronizacji pomiędzy źródłem (alpha) i celem (beta), która na samym początku rozpoznaje użyte środowiska, aby uruchomić na nich proces „agenta„. Agenci komunikują się między sobą za pomocą dobranego protokołu (SCP, Docker API i inne) i obserwują zmiany na plikach. Dalsze działanie, przenoszenie zmian, ignorowanie konkretnych plików, zarządzanie uprawnieniami i symlinkami konfigurowalne jest za pomocą pliku yaml.

Od wersji 0.10 Mutagen wspiera również orkiestrację synchronizacji na poziomie projektu (https://mutagen.io/documentation/orchestration/) oraz kierowanie ruchem sieciowym (https://mutagen.io/documentation/forwarding/).

Poniżej przedstawiam przykładową konfigurację synchronizacji plików dla aplikacji Symfony Demo w systemie OSX z pomocą Mutagena w wersji 0.10.

Zacznijmy od instalacji Mutagena:

 brew install mutagen-io/mutagen/mutagen

Po instalacji należy uruchomić daemon process aplikacji i zarejestrować go w autostarcie systemu:

mutagen daemon start
mutagen daemon register

Mając uruchomioną aplikację Docker, z odpowiednimi kontenerami PHP i Nginx, oczekującymi na pliki w katalogu /var/www/symfony możemy uruchomić nasze sesje synchronizacji.

➜  docker-compose up -d
Creating network "sync-example_default" with the default driver
Creating sync-example_mysql_1 ... done
Creating sync-example_php_1   ... done
Creating sync-example_nginx_1 ... done


➜  docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                               NAMES
f1382f624b00        sync-example_nginx   "nginx"                  15 seconds ago      Up 13 seconds       0.0.0.0:80->80/tcp                  sync-example_nginx_1
a6f42a5c3c89        sync-example_php     "php-fpm7 -F"            16 seconds ago      Up 14 seconds       0.0.0.0:9000->9001/tcp              sync-example_php_1
1a9cec92ed8e        mysql:5.7            "docker-entrypoint.s…"   17 seconds ago      Up 15 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   sync-example_mysql_1

Tworzymy plik mutagen.yml z przykładową zawartością:

sync:
  defaults:
    ignore:
      paths:
        - .DS_Store
  code:
    alpha: "./symfony"
    beta: "docker://sync-example_php_1/var/www/symfony"
    mode: "one-way-safe"
    ignore:
      vcs: true
      paths:
        - "/build/"
        - "/vendor/"
        - "/var/"
  composerjson:
    alpha: "./symfony/composer.json"
    beta: "docker://sync-example_php_1/var/www/symfony/composer.json"
    mode: "two-way-resolved"
    watch:
      pollingInterval: 2
    permissions:
      defaultFileMode: 666
      defaultDirectoryMode: 777
    ignore:
      vcs: false
    symlink:
      mode: "ignore"
  composerlock:
    alpha: "./symfony/composer.lock"
    beta: "docker://sync-example_php_1/var/www/symfony/composer.lock"
    mode: "two-way-resolved"
    watch:
      pollingInterval: 2
    permissions:
      defaultFileMode: 666
      defaultDirectoryMode: 777
    ignore:
      vcs: false
    symlink:
      mode: "ignore"
  var:
    alpha: "./symfony/var"
    beta: "docker://sync-example_php_1/var/www/symfony/var"
    mode: "two-way-resolved"
    watch:
      pollingInterval: 5
  vendor:
    alpha: "./symfony/vendor"
    beta: "docker://sync-example_php_1/var/www/symfony/vendor"
    mode: "two-way-resolved"
    watch:
      pollingInterval: 5
    ignore:
      vcs: false

Zawartość pliku należy dostosować do swoich nazw kontenerów (format to docker://NAZWA_KONTENERA/SCIEZKA). Poszczególne klucze w pliku wyjaśnione są w dokumentacji pod adresem https://mutagen.io/documentation/. Podczas tworzenia konfiguracji, należy zwrócić uwagę na klucze „mode„, „pollingInterval” oraz na wielkość synchronizowanych katalogów. Każdy z tych elementów ma wpływ na wydajność i obciążenie generowane przez procesy „mutagen agent” w kontenerach i na hoście.

Moje doświadczenia potwierdzają, że nawet bardzo duży projekt może być synchronizowany w całości z minimalny obciążeniem CPU. Warunkiem koniecznym jest dobranie odpowiedniej konfiguracji, nawet kosztem dużej ilości sesji mutagena.

Tworzymy nasz projekt Symfony Demo w katalogu symfony:

composer create-project symfony/symfony-demo symfony

Następnym krokiem będzie uruchomienie stworzonych sesji projektu:

mutagen project create mutagen.yml

W rezultacie otrzymamy listę ID utworzonych sesji. Aby sprawdzić ich status należy wywołać komendę

mutagen list

Aby obserwować zachodzące zmiany oraz status transferowanych plików, możemy użyć komendy:

mutagen monitor {ID_SESJI}

Już po paru sekundach na naszych kontenerach znajduje się cała zawartość projektu. Pliki vendora będą synchronizowane dwustronnie, a pliki projektu jednostronnie (w przypadku ewentualnych konfliktów zostaną one wyświetlone po użyciu mutagen list).

Powyższa konfiguracja jest jedną z bardziej skomplikowanych. Jeżeli interesuje nas synchronizacja tylko jednego katalogu (np. konfiguracji PHP w obrazie) wystarczy, że wywołamy komendę:

mutagen create -m two-way-safe docker://sync-example_php_1/etc/php7 ~/Desktop/php

a na naszym pulpicie pojawi się synchronizowany katalog z kontenera, w praktyce działający tak szybko, jak gdyby był podmontowany.

Sesje możemy oczywiście w dowolnej chwili zatrzymywać i wznawiać, usuwać i tworzyć. Nad wszystkim panuje aplikacja.

Podsumowując, uważam, że dzięki Mutagenowi synchronizacja plików nie jest już smutną koniecznością, a narzędziem, które stwarza nowe możliwości. Możemy na przykład w prosty sposób pozbyć się obciążenia komputera, wynosząc warstwy aplikacji poza lokalne środowisko, działając jedynie na IDE.

Serdecznie polecam to narzędzie oraz zachęcam do wspierania twórcy.

Podczas tworzenia artykułu, korzystałem z poniższych linków:
https://mutagen.io/
https://github.com/mutagen-io/mutagen
https://github.com/symfony/demo
https://github.com/coloso/symfony-docker

Autorem tekstu jest Janusz Maciejewski.