Jak korzystając z wirtualizacji przyspieszyliśmy pracę całego zespołu
Czy kiedykolwiek chciałeś zacząć pracować nad świetnym projektem, ale proces konfiguracji wszystkich zależności trwał tak długo, że stopniowo traciłeś motywację? Może chciałeś dodać nowy mikroserwis do aplikacji, ale ilość zmian w procesie deploymentu, którą by to za sobą pociągnęło była zbyt przytłaczająca? A może zdarzył Ci się kiedyś błąd, który występował jedynie na produkcji, a na żadnym innym środowisku nie dało się go zreprodukować?
Jeśli na którekolwiek z wyżej wymienionych pytań odpowiedziałeś tak, ten artykuł jest dla Ciebie! A jeśli jesteś szczęściarzem, który uniknął tych problemów — nadal możesz skorzystać z naszych technik, aby przyspieszyć swoją pracę.
Kacper Kula. Developer Evangelist w SwingDev. Pasjonat nowych technologii pracujący w JavaScript od prawie dekady. Uwielbia dzielić się swoją wiedzą, zarówno na meetupach czy warsztatach, jak i na blogu SwingDev Insights. Prywatnie zapalony fotograf i gracz.
Spis treści
Złożoność architektoniczna
Każdy projekt jest inny. Różnice mogą występować zarówno na poziomie wymagań biznesowych, jak i również przyjętej architektury aplikacji. Czasami Twoje projekty mogą być prostymi aplikacjami składającymi się z frontendu i backendu łączącego się z bazą danych, innym razem aplikacja może składać się z tysiąca mikroserwisów komunikujących się ze sobą, kilku baz danych z różnymi poziomami retencji oraz brokerami i dispatcherami próbującymi okiełznać ten chaos.
Spróbuj pomyśleć o najbardziej złożonym projekcie nad jakim zdarzyło Ci się pracować. Jak trudno byłoby Ci go skonfigurować na nowej maszynie dla nowego programisty dołączającego do Twojego zespołu? Istnieją duże szanse, że zajęłoby to godziny, jeśli nie dni. Przecież trzeba skonfigurować bazy danych, kolejki, zainstalować wszystkie zależności. Gdyby tak istniał sposób, aby to wszystko zautomatyzować i uniezależnić od platformy?
Wirtualizacja
Jednym z rozwiązań, które może pomóc w ogarnięciu chaosu zależności w projekcie jest wirtualizacja. Tego rozwiązania nie można nazwać nowym — już w latach 60. i 70. XX wieku było używane na mainframe’ach, aby zarządzać przydziałem czasu procesora dla konkretnych użytkowników. Gdy kupujesz serwer wirtualny, dostajesz dostęp właśnie do zwirtualizowanego środowiska. Jednak w samym procesie tworzenia oprogramowania i zarządzania projektem, nadal to rozwiązanie nie zaadaptowało się szeroko.
Głównym problemem wirtualizacji był narzut pracy jaki powodował. Wcześniejsze rozwiązania wirtualizacyjne pozwalały na bardzo dużo, jednak ich konfiguracja była czasochłonna. To rozwiązanie było świetne na serwery, jednak w procesie tworzenia oprogramowania mogło być dość męczące.
Z pomocą przyszedł Docker, który rozwiązał większość problemów związanych z konfiguracją. Kilkoma prostymi komendami jesteśmy w stanie ustawić nową wirtualną maszynę z dowolną konfiguracją jaka nam się wymarzy. Docker Compose pozwala na wyabstrahowanie całej konfiguracji architektury aplikacji do jednego pliku, który może być łatwo współdzielony w osobnym repozytorium.
Ten artykuł nie jest wstępem ani do Dockera, ani do wirtualizacji. Zamiast tego, chciałbym pokazać jak korzystając z kilku technik, które działają u nas, można przyspieszyć proces tworzenia, testowania i wdrażania oprogramowania.
Główne repozytorium — bootstrap
Wierzymy w to, że konfiguracja każdego projektu powinna przebiegać w ten sam sposób, niezależnie czy tworzysz prostą aplikację frontendową, czy rozwiązanie z tysiącem mikroserwisów. Dlatego centralnym punktem każdego naszego projektu jest repozytorium bootstrap, w którego skład wchodzą pliki konfiguracyjne (np. nginxa), spis modułów aplikacji oraz plik docker-compose, który opisuje konfigurację i zależności pomiędzy modułami. Za pomocą prostej komendy możemy ściągnąć wszystkie zależne moduły, zaktualizować je, lub dodać nowe. Najważniejsze: uruchomienie całego projektu sprowadza się do wywołania jednej komendy.
Po uruchomieniu projektu możemy zająć się pracą nad jednym lub wieloma modułami. Dzięki możliwości skonfigurowania live-reload dla poszczególnych serwisów, możemy pracować bez konieczności ręcznego przebudowywania projektu za każdym razem.
Czasami projekty, nad którymi przyjdzie nam pracować są tak duże, że nie ma możliwości uruchomić ich całych na jednej maszynie. Korzystając z tego rozwiązania możemy uruchomić tylko część projektu. Jeśli zdefiniujemy w docker-compose.yml dependencies pomiędzy serwisami, możemy uruchomić jedynie serwisy, które są niezbędne do działania modułu, nad którym pracujemy.
Dodatkowo, poprzez przygotowanie odpowiednich danych testowych, które będą automatycznie ładowane do bazy danych, możemy zapewnić, że u wszystkich deweloperów baza zostanie stworzona z najświeższymi danymi. Pomaga to uniknąć problemów, gdzie nie można dostać się do panelu administracyjnego, bo trzeba ręcznie utworzyć konto administratora w bazie. Jeśli dane zostaną dobrze przygotowane, od razu na etapie tworzenia aplikacji można znaleźć potencjalne problemy wydajnościowe lub niezaplanowane sytuacje brzegowe.
Zdarzyło mi się pracować nad projektem, który nie był przygotowany w ten sposób. Brałem w nim udział jako programista frontendowy i ze zdziwieniem, po ponad roku, odkryłem, że zespół backendowy nigdy nie skonfigurował frontendu i nigdy nie “przeklikał” się przez aplikację — wręcz nie wiedzieli jak wygląda i zachowuje się produkt, który tworzą. Głównym powodem tej sytuacji była trudność konfiguracji i utrzymania dodatkowego komponentu. Korzystając z naszego rozwiązania, frontend u każdego budowałby się automatycznie i nie byłoby żadnej przyczyny, aby z niego nie korzystać podczas pracy.
Jak mam z tego skorzystać?
Ostatnio postanowiliśmy upublicznić nasze rozwiązanie, więc możesz zacząć korzystać z niego od zaraz. Wejdź na GitHuba projektu, skopiuj repozytorium i rozpocznij konfigurację. Cały proces jest bardzo prosty, polega na dodaniu nowych modułów (takich jak repozytorium frontendowe lub backendowe), konfiguracji docker-compose i odpaleniu projektu. Wszystko jest opisane szczegółowo w repozytorium.
Po skonfigurowaniu projektu, uruchomienie go polega jedynie na wykonaniu komendy “./bootstrap.sh up”. Po jej wykonaniu projekt jest uruchomiony!
Zalety bootstrapa
Korzystanie z repozytorium bootstrapowego ma wiele korzyści. Deweloperzy otrzymują rozwiązanie, które przyspieszy proces konfiguracji środowiska oraz pracę. Nawet jeśli w projekcie pojawi się nowy moduł, pisany w egzotycznej technologii, zacznie on po prostu działać, bez konieczności dodatkowych ustawień.
Administratorzy i devopsi otrzymują recepty, jak konfigurować projekt. Repozytorium pełni rolę żyjącej dokumentacji architektury aplikacji. Rozwiązanie to pozwala również na zautomatyzowanie testów end-to-end. Korzystając z tej samej konfiguracji jesteśmy w stanie uruchomić środowiska testowe i przeprowadzić na nich automatyczne oraz manualne testy.
Jeśli masz pomysł na nowe funkcje, jesteśmy otwarci na sugestie i pull requesty.
Zdjęcie główne artykułu pochodzi z stocksnap.io.