Docker na Macu, jak go przyspieszyć?

|

TLDR: Przerzuć się na Linuxa 😇

W czym w ogóle jest problem?

Docker na Macu ma poważne problemy z wydajnością od samego początku. Głównym winowajcą jest tutaj współdzielony system plików - osxfs. Jest to szczególnie problematyczne w aplikacjach wykonujących wiele operacji dyskowych.

To czemu po prostu nie kupić „normalnego” komputera z linuxem?

Na samym początku, jak pewnie wielu z Was byłem użytkownikiem Windowsa. Dość szybko okazało się jednak, że nie jest to zbyt dobry system dla programisty. Przede wszystkim wolę wpisywać komendy w terminalu, zamiast klikać w te wszystkie piękne ikonki. Nie mogę też nie wspomnieć, że Symfony, czyli framework, z którym zaczynałem karierę i pracuję w nim do teraz, działał na Windowsie bardzo wolno.

Niestety miałem tylko jeden komputer, zarówno do pracy, jak i szeroko rozumianej rozrywki. Linux, choć świetnie nadaje się do pracy, nie spełniał moich wymagań, jeśli chodzi o ten drugi aspekt.

Postanowiłem spróbować jeszcze jednej alternatywy, tak oto stałem się posiadaczem Macbooka Pro. W moim odczuciu MacOS całkiem dobrze łączy zalety unixowego systemu z zaletami Windowsa.

To były jeszcze czasy przed Dockerem, trzeba było instalować i konfigurować środowisko ręcznie, ale przynajmniej nie było problemu z wydajnością.

Wszystko było super do momentu, kiedy zaczęliśmy w Accesto używać Dockera…

Da się coś z tym zrobić?

Tak jak już wspomniałem, używaj Linuksa.

Dobra, odłóżmy żarty na bok (czy aby na pewno jest to żart?) i zbadajmy parę możliwości.

Metodologia pomiarów

Wszystkie pomiary były przeprowadzane na tym samym projekcie, z tymi samymi danymi i w taki sam sposób. Testowałem endpoint API za pomocą narzędzia Apache Benchmarking tool.

Sto zapytań, jedno po drugim. Do testów użyłem jednego z naszych projektów, oczywiście w trybie dev, czyli dokładnie to samo, z czym pracuję na co dzień.

Dodatkowo sprawdziłem jak dużo czasu potrzeba na zbudowanie obrazu dockera, dla każdego z tych rozwiązań. Może nie jest to coś, co robi się codziennie, ale i tak fajnie, jeśli nie trzeba czekać godziny na zbudowanie obrazu.

Żeby mieć jakiś punkt odniesienia, poprosiłem jednego ze współpracowników, żeby przeprowadził podobny test na jego komputerze. Komputerze ze znacznie większą pamięcią RAM, mocniejszym procesorem, dyskiem SSD i Linuksem na pokładzie.

Docker Container

Docker na Macu - różne opcje konfiguracji wolumenów

Docker udostępnia trzy opcje konfiguracji spójności w definicji wolumenów:

  • consistent (default) - spójne (zarówno host jak i kontener mają cały czas identyczne wersje plików)
  • cached - host ma priorytet (zmiany w kontenerze mogą pojawić się z opóźnieniem)
  • delegated - kontener ma priorytet (zmiany w hoście mogą pojawić się z opóźnieniem)

Różne ustawienia mogą wpływać na wydajność aplikacji, niektóre źródła podają, że taka zmiana może znacznie przyspieszyć Dockera na Macu.

Jeśli korzystasz z docker-compose wtedy wystarczy dodać odpowiednią opcję do definicji wolumenu.

version: '3'
services:
  web:
    build: .
    volumes:
      - ./:/var/www:cached
Docker on Mac performance

Jak łatwo zauważyć na powyższym wykresie, Docker na Macu jest wolny, bardzo wolny. Są drobne różnice między dostępnymi opcjami, ale nie są one znaczące, a wręcz niezauważalne.

Możesz poeksperymentować w Twoim konkretnym projekcie, może uda się coś poprawić, choć prawdopodobnie zysk nie będzie zbyt duży.

Docker na Macu - Mutagen

Mutagen to open-sourcowe narzędzie stworzone do szybkiej i niezawodnej synchronizacji plików. Istnieją inne rozwiązania tego typu, np. docker-sync, ale Mutagen jest obecnie bardziej wydajny i stabilniejszy.

A co najważniejsze, może być użyty do pracy z Dockerem.

Konfiguracja z wykorzystaniem docker-compose jest łatwa, wystarczy skonfigurować wolumen

volumes:
  code:

użyć go w konkretnym serwisie

web:
    build: .
    volumes:
      - code:/code

a następnie skonfigurować mutagen do synchronizacji plików z hosta do zdefiniowanego wolumenu

x-mutagen:
  sync:
    defaults:
      ignore:
        vcs: true
    code:
      alpha: "."
      beta: "volume://code"
      mode: "two-way-resolved"

Kompletny przykład pliku docker-compose.yml można znaleźć tutaj

Oczywiście trzeba najpierw zainstalować i uruchomić mutagena.

Na pierwszy rzut oka może to wyglądać skomplikowanie, ale tak naprawdę jest to proste, a zysk na tyle duży, że na prawdę warto.

Docker on Mac with Mutagen performance

Na tym wykresie widać porównanie szybkości działania aplikacji z zastosowaniem mutagen, z poprzednimi wynikami. Poprawa jest znaczna, w mojej opinii mutagen to na obecną chwilę najlepsza opcja na przyspieszenie aplikacji (jeśli w dalszym ciągu chcesz używać Dockera na Macu).

Linux

Z tym Linuksem to nie żartowałem, na prawdę warto tę opcję wziąć pod uwagę. Testowałem dwa rozwiązania, VirtualBox i VPS.

Oba sprawdzały się całkiem dobrze.

Linux w VirtualBox

Na pomysł użycia maszyny wirtualnej wpadłem jeszcze przed tym, jak pojawił się mutagen. Korzystałem z tego rozwiązania dość długo, zanim przerzuciłem się na inne, choć podobne.

Jest trochę zabawy z konfiguracją, ponieważ trzeba:

  1. skonfigurować maszynę wirtualną i całe Linuksowe środowisko
  2. poprawnie ustawić sieci
  3. oraz skorzystać z jakiegoś narzędzia do synchronizacji plików

Na szczęście wystarczy to zrobić tylko raz. Nie opiszę wszystkich technicznych szczegółów tego podejścia, nie jest to tematem tego posta. Opiszę jedynie krótko moje sposoby na synchronizowanie plików.

Synchronizacja plików

PhpStorm

Prawdopodobnie każdy deweloper PHP zna to IDE, prawdopodobnie większość z Was go używa. Natomiast możliwe, że nie każdy wie, że umożliwia ono również synchronizowanie plików. To wbudowane narzędzie nazywa się Deployment i działa choćby przez SFTP.

Jest łatwe w konfiguracji, wspiera automatyczny upload i wiele więcej. Dzięki temu możesz pracować na swoim Macu, a wszystkie zmiany będą wysyłane do maszyny wirtualnej z działającym Dockerem. Testować aplikację możesz również na Macu, tylko zamiast localhost w pasku przeglądarki wpiszesz IP maszyny.

Dzięki temu Docker już nie działa na Macu, a na Linuksie więc nie sprawia tylu problemów.

Jedyny minus użycia PhpStorm w tym celu to synchronizacja wielu plików jednocześnie (np. przy zmianie brancha), są wtedy wysyłane pojedynczo, co potrafi zająć trochę czasu.

Mutagen

Mutagen pojawił się stosunkowo niedawno, był też trochę niestabilny na początku. Dlatego przez pewien czas korzystałem z wyżej wymienionego rozwiązania.

Przyszedł jednak moment, kiedy zdecydowałem się przetestować mutagen.

Konfiguracja jest całkiem prosta, można mieć osobny plik konfiguracyjny dla każdego projektu. Wystarczy utworzyć plik o nazwie mutagen.yml w katalogu projektu z podobną zawartością:

sync:
  defaults:
    ignore:
      paths:
        - .DS_Store
  project-code:
    alpha: ~/work/project
    beta: ubuntu@192.168.0.123:~/work/project
    mode: "two-way-resolved"
    configurationBeta:
       permissions:
          defaultFileMode: 0664
          defaultDirectoryMode: 0755
    symlink:
       mode: "posix-raw"
    ignore:
      vcs: true
      paths:
        - "/build/"
        - "/var/"
        - "/node_mudules/"

Gdzie alpha to host a beta to maszyna wirtualna.

mutagen project start - uruchamia synchronizację.

Od tego momentu wszystkie pliki będą automatycznie trafiać do maszyny wirtualnej, praktycznie bez żadnych opóźnień. Całość działa stabilnie i bez większych problemów.

Dużą przewagą tego rozwiązana nad tym wbudowanym w PhpStorm jest to, że mutagen w przypadku większej liczby zmian, tworzy “paczki” i wysyła je jednocześnie, co znacznie przyspiesza synchronizację.

Czas na testy

W tym przypadku również testowałem różne opcje konfiguracji wolumenów. Dla porównania dodałem wyniki Dockera na macu (wersja z mutagenem).

Docker on VirtualBox performance

Różnica w przypadku różnych konfiguracji wolumenów jest nieznaczna. Również różnica między Dockerem na Macu (z mutagenem), a Dockerem w VirtualBox jest w granicach błędu pomiarowego.

Linux na zewnętrznym serwerze - VPS

Docker to dość zasobożerne narzędzie, nie ma znaczenia czy używasz go na Macu, czy w maszynie wirtualnej. W każdym przypadku potrzebuje całkiem sporo RAMu i procesora. Oczywiście zawsze można wymienić obecnego Maca na jakiegoś mocniejszego, ale ani to nie są tanie rzeczy, ani zbyt przyjazne dla środowiska. Bo po co wymieniać coś co jest jeszcze dobre.

Tańszą alternatywą jest przeniesienie Dockera na zewnątrz, VPS nadaje się do tego całkiem dobrze. Wszystkie obciążające komputer zadania mogą być wykonane przez inną maszynę, działająca na Linuksie, bez tych wszystkich problemów związanych z wydajnością. To rozwiązanie ma jeszcze taką zaletę, że jest łatwo skalowalne, dodanie więcej RAMu, CPU czy dysku to żaden problem,

Sama konfiguracja nie różni się zbytnio od VirtualBox. Główna różninca to fakt, że VPS jest dostępny “z zewnątrz”, więc dobrze by było poprawnie zabezpieczyć serwer.

Nie jest to oczywiście trywialne zadanie, ale myślę, że każdy znający podstawy DevOpsu da sobie z tym radę.

Docker on VPS performance

Docker na VPS

Używam dość taniego VPS, o dość słabych parametrach, ma nawet mniej RAMu niż miałem wcześniej przydzielone do maszyny wirtualnej. Prawdopodobnie dlatego, wypadł trochę gorzej.

Trochę gorsze wyniki to jednak nie wszystko. Główną zaletą tego rozwiązania jest to, że Docker nie używa w ogóle zasobów Maca, więc cały system działa szybciej. Wentylatory nie chodzą na najwyższych obrotach, da się normalnie pracować podczas budowania obrazu, po prostu wszystko działa zdecydowanie lepiej.

Nic dziwnego, skoro Docker nie pożera już zasobów.

Obecnie używam tego rozwiązania. Zmieniłem VirtualBox na VPS parę miesięcy temu i jestem bardzo zadowolony.

Porównanie czasu budowania obrazu

Docker build time

Budowanie obrazu Dockera to kolejny aspekt, o którym warto wspomnieć. Choć nie robi się tego codziennie, to jednak zdarza się, że trzeba taki obraz zbudować od zera. Jest to dość czasochłonny proces, zależy od wielu czynników. Może trwać kilka minut, może godzinę, a pewnie i dłużej.

Jak widać Docker na Macu jest wolny nie tylko w przypadku przetwarzania requestów, jest jeszcze gorzej w przypadku budowania obrazu.

Mutagen na Macu przyspiesza znacznie ten proces, do nieco ponad pół godziny. Podobny czas jest potrzebny w przypadku maszyny wirtualnej.

Co ciekawe, ten sam test przeprowadzony na VPS wypadł zdecydowanie lepiej. Może mieć to związek z przepustowością łącza internetowego, VPS zapewne ma dużo lepszy internet niż ten mój domowy.

Oczywiście warto też wspomnieć o tym, że proces budowania obrazu jest jeszcze bardziej zasobożerny niż używanie Dockera normalnie. Nie ma znaczenia czy buduje się go bezpośrednio na Macu czy w VirtualBox, zawsze zużyje wszystko, co jest tylko dostępne. Wszystko działa wtedy tak wolno, że lepiej zrobić sobie przerwę i pójść na spacer.

Podsumowanie

Docker na Macu

Wady:

  • bardzo wolny
  • zasobożerny
  • wymaga dużo przestrzeni dyskowej
  • jeszcze nie w 100% działający na nowych Macach z procesorem M1 (informacja z początku 2021)

Zalety:

  • łatwa konfiguracja - działa “out of the box”

Docker na Macu z Mutagenem

Wady:

  • zasobożerny
  • wymaga dużo przestrzeni dyskowej
  • jeszcze nie w 100% działający na nowych Macach z procesorem M1 (informacja z początku 2021)

Zalety:

  • nie wymaga wielu zmian w konfiguracji
  • jest szybki

Docker w VirtualBox

Wady:

  • zasobożerny
  • wymaga dużo przestrzeni dyskowej
  • bardziej skomplikowana konfiguracja

Zalety:

  • jest szybki
  • obraz VirtualBox może być zapisany na zewnętrznym dysku, żeby oszczędzić miejsce na tym wbudowanym

Docker na VPS

Wady:

  • bardziej skomplikowana konfiguracja
  • nie jest to darmowe rozwiązanie, trzeba opłacać VPS
  • wymagany jest dostęp do internetu

Zalety:

  • jest szybki
  • nie zużywa zasobów Maca
  • zawsze można wykorzystać VPS również do innych celów
  • jest dostępny z każdego urządzenia

Dla mnie wybór jest prosty, wolę opłacić VPS i mieć szybkie, niezawodne środowisko dla projektów wymagających Dockera. Nie jest to najtańsza opcja, choć i tak pewnie tańsza niż inwestowanie w Macbooka z wystarczająco dużym dyskiem, wydajnym CPU i na tyle dużą ilością RAMu, żeby obsłużyć Dockera, IDE, przeglądarkę i wszystkie inne narzędzia w tym samym czasie.

Poświęcenie czasu na poprawę Twojego setupu Dockera na pewno się opłaci i zaoszczędzi sporo czasu i nerwów w przyszłości. Jeśli korzystasz z Dockera na co dzień koniecznie zerknij na darmowego ebooka gdzie znajdziesz wiele sposobów na dalsze optymalizacje - Docker Deep Dive.

15 quick docker tips

Podziękujesz mi później ;)

Zobacz też:

Dodaj na LinkedIn
Krzysztof Lobermajer
Symfony Developer w Accesto. Fan czystego kodu oraz prostych rozwiązań. Gdy nie programuje pochłania się w degustacji whisky.