„Zainstaluj linuxową maszynę wirtualną i odtwórz dokładnie to samo środowisko.”
Trzy miesiące po moim dołączeniu do firmy atmosfera w biurze była niepokojąca. Jedyny senior w zespole miał zostać przeniesiony do innego projektu i był tak zajęty pakowaniem własnych rzeczy, że o sensownym przekazaniu wiedzy nie było mowy, a team leader od dawna nie zajmował się już praktycznym developmentem i był dość daleko od aktualnych trendów technologicznych.
Pewnego dnia team leader zawołał mnie do siebie. „Kiedy twój senior odejdzie, jedyną osobą, która będzie mogła ogarniać serwery, będziesz ty. Nawet jeśli serwer padnie, musisz umieć sam go postawić. Zainstaluj Linuxa jako maszynę wirtualną, VM, na swoim obecnym laptopie deweloperskim, Windows, i spróbuj odtworzyć dokładnie to samo środowisko co na serwerze produkcyjnym.”
Od tego dnia zaczęła się moja udręka. Zainstalowałem VMware, pobrałem plik ISO Ubuntu, a samo postawienie systemu zajęło mi pół dnia. Przekopywałem firmową wiki, żeby zainstalować Javę, Node.js i PostgreSQL. Pomyślałem: „Nowsze będzie lepsze”, więc wrzuciłem Javę 17, po czym okazało się, że legacy code opiera się na Javie 8 i nawet się nie buduje. Musiałem wszystko usuwać i instalować od nowa. Za każdym razem, gdy zmieniałem jedną linijkę kodu, musiałem odpalać mvn build, przenosić plik jar do VM i uruchamiać go tam. To była czysta męka.
W pewnym momencie naszła mnie myśl. „Chwileczkę. Ostatnim razem, kiedy wdrażaliśmy na serwer produkcyjny, czy to nie skończyło się po wpisaniu jednej komendy docker service update?”
Moja lokalna maszyna wirtualna była tak ciężka i wymagała góry konfiguracji, więc czym właściwie był ten cały „Docker” na serwerze produkcyjnym, skoro pozwalał wszystko zaktualizować jedną komendą?

Ciężkie rozwiązanie: maszyna wirtualna
Metoda, którą kazał mi zastosować team leader, czyli zainstalowanie Linuxa na Windowsie, to dokładnie to, czym jest maszyna wirtualna, VM. To tak, jakby na fizycznym komputerze, host, zbudować całkowicie osobny „wirtualny dom”, czyli guest OS.
Ostatecznie VM rzeczywiście dobrze izoluje środowisko, ale do developmentu czy deploymentu jest po prostu zbyt ciężka i zbyt wolna, żeby za każdym razem ją przerzucać tam i z powrotem.
Lekka rewolucja: Docker
Dlatego pojawił się Docker, czyli technologia kontenerów. Docker nie buduje całego domu tak jak VM. Zamiast tego rozstawia namiot.
Polecenie update, które uruchomiłem na serwerze produkcyjnym, nie instalowało od nowa ciężkiego systemu operacyjnego. Ono tylko „zwijało stary namiot i rozstawiało nowy z nową wersją kodu w środku”. Nic dziwnego, że kończyło się niemal natychmiast.

[Code Verification] Czy Docker naprawdę jest taki lekki?
Nie poprzestawajmy na samym mówieniu, że Docker jest lekki. Sprawdźmy to naprawdę. Jeśli celem jest uruchomienie środowiska Linux, Ubuntu, różnica między VM a Dockerem jest uderzająca.
# Uruchom Ubuntu komenda Docker (pobiera obraz, jesli brak)
$ docker run -it ubuntu:latest /bin/bash
Wynik:
W chwili, gdy nacisnąłem Enter, byłem już w środowisku Ubuntu. To jest możliwe, ponieważ kontener Docker nie jest prawdziwym systemem operacyjnym. To jedynie „izolowana przestrzeń, która pożycza kernel host OS, czyli mojego komputera, jednocześnie udając osobny OS”.
Praktyczna rada: prawdziwy powód, żeby używać Dockera
Odkąd wdrożyliśmy Dockera w pracy, moje życie zmieniło się całkowicie.
Na koniec: nie dostarczamy już pliku wykonywalnego, tylko „środowisko”
Pojawienie się Dockera zmieniło paradygmat developmentu. Nie wysyłamy już na serwer samego kodu źródłowego, .java. Zamrażamy też konfigurację systemu operacyjnego, biblioteki i zmienne środowiskowe potrzebne temu kodowi w postaci „obrazu” i wysyłamy cały pakiet.
To jak właściwie powstaje ten magiczny „obraz Dockera”? Czy to po prostu skompresowany plik? Co zaskakujące, mówi się, że obraz Dockera składa się z wielu warstw, jak tort.
Następnym razem przyjrzyjmy się sekretowi wydajności Dockera: obrazom i ich warstwowej strukturze.