Proces tworzenia i testowania z Docker i Gitlab CI

Zapraszam do zapoznania się z transkrypcją wystąpienia Aleksandra Sigačewa z Inventos "Proces opracowywania i testowania z Docker + Gitlab CI"

Ci, którzy dopiero zaczynają wdrażać proces rozwijania i testowania opartego na Docker + Gitlab CI, często zadają podstawowe pytania. Od czego zacząć? Jak to zorganizować? Jak testować?

Ten referat jest dobry, ponieważ w sposób zorganizowany opisuje proces rozwijania i testowania przy użyciu Docker i Gitlab CI. Sam referat pochodzi z 2017 roku. Myślę, że można w nim znaleźć podstawy, metodologię, pomysły i doświadczenie związane z użytkowaniem.

Odtwarzaj wideo

Kogo to interesuje, zapraszam dalej.

Nazywam się Aleksandr Sigaczew. Pracuję w firmie Inventos. Opowiem o swoim doświadczeniu z Dockerem i o tym, jak stopniowo wdrażamy go w projektach w firmie.

Temat referatu: Proces rozwijania przy użyciu Docker i Gitlab CI.

Proces tworzenia i testowania z Docker i Gitlab CI

To mój drugi referat o Dockerze. W momencie pierwszego wystąpienia używaliśmy Dockera tylko w Development na maszynach programistów. Liczba pracowników korzystających z Dockera wynosiła około 2-3 osób. Stopniowo zdobyliśmy doświadczenie i posunęliśmy się trochę dalej. Link do naszego pierwszego referatu.

Co będzie w tym referacie? Podzielimy się doświadczeniem, jakie problemy napotkaliśmy i jak je rozwiązaliśmy. Nie wszędzie było to piękne, ale pozwoliło nam iść dalej.

Nasze hasło: dockerizuj wszystko, do czego sięgną nasze ręce.

Proces tworzenia i testowania z Docker i Gitlab CI

Jakie problemy rozwiązujemy?

Kiedy w firmie jest kilka zespołów, programista jest zasobem o wszechstronnym zastosowaniu. Bywają etapy, kiedy programistę wyciągają z jednego projektu i przydzielają na trochę czasu do innego projektu.

Aby programista szybko się wprowadził, musi pobrać kod źródłowy projektu i jak najszybciej uruchomić środowisko, które pozwoli mu kontynuować pracę nad zadaniami danego projektu.

Zwykle, jeśli zaczyna się od zera, to dokumentacji w projekcie jest mało. Informacje o tym, jak skonfigurować, mają tylko starzy wyjadacze. Sami pracownicy konfigurują swoje miejsca pracy w ciągu jednego-dwóch dni. Aby to przyspieszyć, zastosowaliśmy Dockera.

Następnym powodem jest standaryzacja ustawień w Development. Z mojego doświadczenia wynika, że programiści zawsze wykazują inicjatywę. W co piątym przypadku wprowadza się niestandardową domenę, na przykład vasya.dev. Obok siedzi sąsiad Petya, który ma domenę petya.dev. Tworzą stronę lub jakiś komponent systemu, używając tej nazwy domeny.

Kiedy system się rozrasta, a te domeny zaczynają pojawiać się w konfiguracjach, pojawia się konflikt środowisk Development i zmienia się ścieżka do strony.

To samo dotyczy ustawień bazy danych. Ktoś nie przejmuje się bezpieczeństwem i pracuje z pustym hasłem root. Ktoś inny podczas instalacji MySQL wymagał hasła i miał hasło 123. Często zdarza się, że konfiguracja bazy danych zmieniała się w zależności od commitów programisty. Ktoś poprawił, ktoś nie poprawił konfiguracji. Były sztuczki, kiedy przenosiliśmy jakąś testową konfigurację do .gitignore i każdy programista musiał instalować bazę danych. To skomplikowało proces uruchamiania. Oprócz wszystkiego innego należy pamiętać o bazie danych. Bazę danych trzeba zainicjować, trzeba wpisać hasło, trzeba wpisać użytkownika, stworzyć tabelkę i tak dalej.

Kolejnym problemem są różne wersje bibliotek. Często zdarza się, że programista pracuje z różnymi projektami. Jest projekt Legacy, który zaczęto pięć lat temu (od 2017 roku – przyp. red.). Na początek zaczęto z MySQL 5.5. Są też nowoczesne projekty, w których staramy się wprowadzać już bardziej nowoczesne wersje MySQL, na przykład 5.7 lub starsze (w 2017 roku – przyp. red.)

Ten, kto pracuje z MySQL, wie, że te biblioteki pociągają za sobą zależności. Dosyć problematyczne jest uruchomienie 2 baz jednocześnie. Przynajmniej starych klientów problematycznie podłączyć do nowej bazy danych. To z kolei rodzi kilka problemów.

Następnym problemem jest sytuacja, gdy programista pracuje na lokalnej maszynie, używając lokalnych zasobów, lokalnych plików, lokalnej pamięci RAM. Cała interakcja podczas opracowywania rozwiązań odbywa się w ramach tego, co działa na jednej maszynie. Przykładem może być sytuacja, gdy mamy 3 serwery backendowe w produkcji, a programista zapisuje pliki w katalogu głównym, a stamtąd nginx pobiera pliki w odpowiedzi na zapytania. Kiedy taki kod trafia do produkcji, okazuje się, że plik znajduje się na jednym z 3 serwerów.

Obecnie rozwija się koncepcja mikroserwisów. Dzielimy nasze duże aplikacje na mniejsze komponenty, które wzajemnie ze sobą współpracują. Umożliwia to wybór technologii odpowiednich do konkretnego stosu zadań. Dodatkowo pozwala to podzielić pracę i odpowiedzialność między programistami.

Frontend-developer, pracując w JS, praktycznie nie wpływa na Backend. Backend-developer, w naszym przypadku, rozwija Ruby on Rails i nie przeszkadza Frontendowi. Współpraca odbywa się za pomocą API.

Dzięki Dockerowi udało nam się zminimalizować zużycie zasobów na Stagingu. Każdy projekt wymagał określonych ustawień, w zależności od swojej specyfiki. Fizycznie trzeba było albo wydzielić po jednym wirtualnym serwerze i osobno je skonfigurować, albo podzielić jakieś wspólne środowisko zmienne i projekty mogły się wzajemnie wpływać w zależności od wersji bibliotek.

Proces tworzenia i testowania z Docker i Gitlab CI

Narzędzia. Czego używamy?

  • Bezpośrednio sam Docker. W Dockerfile opisane są zależności jednego z aplikacji.
  • Docker-compose to zestawienie, które łączy nasze kilka aplikacji Docker.
  • GitLab używamy do przechowywania kodu źródłowego.
  • GitLab-CI używamy do integracji systemowej.

Proces tworzenia i testowania z Docker i Gitlab CI

Prezentacja składa się z dwóch części.

Pierwsza część opowie o tym, jak uruchamialiśmy Dockera na maszynach programistów.

Druga część opowie o tym, jak współpracować z GitLabem, jak uruchamiamy testy i jak wdrażamy na Staging.

Proces tworzenia i testowania z Docker i Gitlab CI

Docker to technologia, która umożliwia (stosując podejście deklaratywne) opisanie niezbędnych komponentów. Oto przykład Dockerfile. Tutaj ogłaszamy, że dziedziczymy od oficjalnego obrazu Dockera Ruby:2.3.0. Zawiera on zainstalowany Ruby w wersji 2.3. Instalujemy niezbędne biblioteki do kompilacji oraz NodeJS. Oznajmiamy, że tworzymy katalog. /app. Ustawiamy katalog app jako bieżący katalog roboczy. Umieszczamy w tym katalogu niezbędny minimalny Gemfile i Gemfile.lock. Następnie wykonujemy budowę projektów, które instalują ten obraz zależności. Wskazujemy, że kontener będzie gotowy na nasłuchiwanie na zewnętrznym porcie 3000. Ostatnie polecenie to polecenie, które bezpośrednio uruchamia nasze aplikacje. Jeśli wykonamy polecenie uruchomienia projektu, aplikacja spróbuje się wykonać i uruchomi podane polecenie.

Proces tworzenia i testowania z Docker i Gitlab CI

To minimalny przykład pliku docker-compose. W tym przypadku pokazujemy, jak następuje połączenie dwóch kontenerów. Chodzi tu o usługę bazy danych oraz usługę web. Nasze aplikacje webowe w większości przypadków wymagają jako backendu pewnej bazy danych do przechowywania informacji. Ponieważ używamy MySQL, przykład dotyczy MySQL — ale nic nie stoi na przeszkodzie, aby użyć innej bazy danych (PostgreSQL, Redis).

Bierzemy z oficjalnego źródła na Docker hub obraz MySQL 5.7.14 bez zmian. Obraz, który odpowiada za nasze web aplikacje, budujemy z bieżącego katalogu. Podczas pierwszego uruchomienia buduje nam obraz. Następnie uruchamia polecenie, które tutaj wykonujemy. Jeśli wrócimy krok wstecz, zobaczymy, że zdefiniowano polecenie uruchomienia przez Puma. Puma to usługa napisana w Ruby. W drugim przypadku nadpisujemy to. To polecenie może być dowolne w zależności od naszych potrzeb lub zadań.

Opisujemy również, że musimy przekazać port na naszej komputerze developerskim z 3000 na 3000 port kontenera. Działa to automatycznie za pomocą iptables i swojego mechanizmu, który jest bezpośrednio zakodowany w Docker.

Developer może również, jak wcześniej, zwrócić się do dowolnego dostępnego adresu IP, na przykład lokalnego 127.0.0.1 lub zewnętrznego adresu IP maszyny.

Ostatnia linijka mówi, że kontener web zależy od kontenera db. Kiedy uruchamiamy kontener web, wcześniej docker-compose uruchomi dla nas bazę danych. Już po starcie bazy danych (w rzeczywistości — po uruchomieniu kontenera! Gotowość Bazy Danych tego nie gwarantuje) uruchomi nam aplikację, nasz backend.

Pozwala to uniknąć błędów, gdy baza danych nie jest uruchomiona i oszczędza zasoby, gdy zatrzymujemy kontener bazy danych, zwalniając tym samym zasoby na inne projekty.

Proces tworzenia i testowania z Docker i Gitlab CI

Co nam daje używanie dokeryzacji bazy danych w projekcie. Rejestrujemy u wszystkich deweloperów wersję MySQL. Pozwala to uniknąć niektórych błędów, które mogą wystąpić w przypadku różnic wersji, gdy zmienia się składnia, konfiguracja, domyślne ustawienia. Umożliwia to wskazanie wspólnego hostname dla bazy danych, loginu, hasła. Odchodzimy od tego zoo nazw i konfliktów w plikach konfiguracyjnych, które były wcześniej.

Mamy możliwość użycia bardziej optymalnej konfiguracji dla środowiska deweloperskiego, która będzie różnić się od domyślnej. MySQL domyślnie jest skonfigurowany do pracy na słabych maszynach i jego wydajność z pudełka jest bardzo niska.

Proces tworzenia i testowania z Docker i Gitlab CI

Docker pozwala korzystać z interpreterów Python, Ruby, NodeJS, PHP w potrzebnych wersjach. Uwalniamy się od konieczności stosowania menedżera wersji. W przeszłości dla Ruby używano pakietów rpm, które pozwalały zmieniać wersję w zależności od projektu. Pozwala to dzięki kontenerom Docker płynnie migrować kod i wersjonować go razem z zależnościami. Nie mamy problemu ze zrozumieniem wersji zarówno interpretera, jak i kodu. Aby zaktualizować wersję, należy usunąć stary kontener i uruchomić nowy kontener. Jeśli coś pójdzie nie tak, możemy usunąć nowy kontener, uruchomić stary kontener.

Po zbudowaniu obrazu kontenery zarówno w środowisku deweloperskim, jak i produkcyjnym będą identyczne. Jest to szczególnie istotne w przypadku dużych instalacji.

Proces tworzenia i testowania z Docker i Gitlab CI Na Frontendzie używamy JavaScript i NodeJS.

Obecnie nasz ostatni projekt oparty jest na ReacJS. Deweloper uruchamiał wszystkie kontenery i rozwijał projekt używając hot-reload.

Następnie uruchamiana jest zadanie kompilacji JavaScript, a skompilowany kod w postaci statyki jest przekazywany przez nginx, oszczędzając zasoby.

Proces tworzenia i testowania z Docker i Gitlab CI

W tym miejscu przedstawiłem schemat naszego ostatniego projektu.

Jakie zadania zostały rozwiązane? Mieliśmy potrzebę zbudowania systemu, z którym współpracują urządzenia mobilne. Odbierają dane. Jedną z możliwości jest wysłanie powiadomień push do danego urządzenia.

Co zrobiliśmy w tym celu?

Podzieliliśmy aplikację na takie komponenty jak: część administracyjna na JS, backend, który działa przez interfejs REST w Ruby on Rails. Backend współpracuje z bazą danych. Wynik, który jest generowany, jest przekazywany klientowi. Panel administracyjny z backendem i bazą danych współpracuje przez interfejs REST.

Mieliśmy również potrzebę wysyłania powiadomień Push. Wcześniej mieliśmy projekt, w którym wdrożono mechanizm odpowiedzialny za dostarczanie powiadomień na platformy mobilne.

Opracowaliśmy taki schemat: operator w przeglądarce interaguje z panelem administracyjnym, panel administracyjny interaguje z backendem, a następnie zostaje zlecone wysłanie powiadomień Push.

Powiadomienia Push współdziałają z innym komponentem, który został wdrożony na NodeJS.

Tworzone są kolejki, a następnie następuje wysyłka powiadomień według własnego mechanizmu.

Tutaj przedstawione są dwie bazy danych. Obecnie używamy przy pomocy Docker dwóch niezależnych baz danych, które nie są ze sobą powiązane. Oprócz tego mają wspólną sieć wirtualną, a fizyczne dane przechowywane są w różnych katalogach na komputerze programisty.

Proces tworzenia i testowania z Docker i Gitlab CI

To samo, ale w liczbach. Ważne jest tutaj ponowne wykorzystanie kodu.

Jeśli wcześniej mówiliśmy o ponownym wykorzystaniu kodu w postaci bibliotek, to w tym przypadku nasza usługa odpowiedzialna za powiadomienia Push jest wykorzystywana jako pełny serwer. Oferuje API, z którym interaguje nasza nowa aplikacja.

W tamtym czasie używaliśmy wersji 4 NodeJS. Teraz (w 2017 roku — przypis red.) w nowych projektach używamy wersji 7 NodeJS. Nie ma problemów z używaniem nowych wersji bibliotek w nowych komponentach.

W razie potrzeby można przeprowadzić refaktoryzację i podnieść wersję NodeJS w usłudze powiadomień Push.

A jeśli będziemy mogli zachować zgodność API, można będzie ją wymienić na innych projektach, które były wcześniej używane.

Proces tworzenia i testowania z Docker i Gitlab CI

Co jest potrzebne aby dodać Docker? Dodajemy do naszego repozytorium Dockerfile, który opisuje niezbędne zależności. W tym przykładzie komponenty są podzielone według logiki. To minimalny zestaw dla backend-developera.

Podczas tworzenia nowego projektu tworzymy Dockerfile, opisujemy potrzebny ekosystem (Python, Ruby, NodeJS). W pliku docker-compose opisujemy niezbędną zależność — bazę danych. Opisujemy, że potrzebna jest baza określonej wersji, by przechowywać dane tam, gdzie jest to wymagane.

Używamy osobnego trzeciego kontenera z nginx do wydawania statycznych zasobów. Przewidziano możliwość przesyłania obrazków. Backend umieszcza je w wcześniej przygotowanej objętości, która jest również zamontowana w kontenerze z nginx, który wydaje statykę.

Aby przechować konfigurację nginx, mysql, dodaliśmy folder Docker, w którym przechowujemy niezbędne konfiguracje. Kiedy deweloper klonuje repozytorium na swoją maszynę, otrzymuje już projekt gotowy do lokalnego rozwoju. Nie ma pytania, jaki port lub jakie ustawienia zastosować.

Proces tworzenia i testowania z Docker i Gitlab CI

Dalej mamy kilka komponentów: admin, inform-API, powiadomienia push.

Aby uruchomić to wszystko, stworzyliśmy kolejne repozytorium, które nazwaliśmy dockerized-app. Na chwilę obecną korzystamy z kilku repozytoriów dla każdego komponentu. Różnią się one tylko logicznie — w GitLab wygląda to jak folder, a na maszynie dewelopera jako folder pod konkretny projekt. Na niższym poziomie znajdują się komponenty, które będą scalane.

Proces tworzenia i testowania z Docker i Gitlab CI

To jest przykład zawartości dockerized-app. Wyciągamy tutaj również katalog Docker, w którym umieszczamy konfiguracje potrzebne do interakcji wszystkich komponentów. Jest README.md, w którym krótko opisano, jak uruchomić projekt.

Zastosowaliśmy tutaj dwa pliki docker-compose. Zrobiono to, aby mieć możliwość uruchamiania stopniowo. Kiedy deweloper pracuje z rdzeniem, nie potrzebuje powiadomień push, więc uruchamia tylko plik docker-compose, co w efekcie oszczędza zasoby.

Jeśli zachodzi potrzeba integracji z powiadomieniami push, uruchamiany jest docker-compose.yaml i docker-compose-push.yaml.

Ponieważ docker-compose.yaml i docker-compose-push.yaml znajdują się w folderze, automatycznie tworzy się jedna wirtualna sieć.

Proces tworzenia i testowania z Docker i Gitlab CI

Opis komponentów. To bardziej rozwinięty plik, który odpowiada za zbieranie komponentów. Co tutaj jest istotne? Wprowadzamy komponent balancer.

To gotowy obraz Docker, w którym uruchamiany jest nginx i aplikacja, która nasłuchuje na sockecie Docker. Dynamicznie, w miarę włączania i wyłączania kontenerów, regeneruje konfigurację nginx. Obsługa komponentów jest rozdzielana po nazwach domen trzeciego poziomu.

Dla środowiska rozwojowego używamy domeny .dev — api.informer.dev. Aplikacje z domeną .dev są dostępne na lokalnej maszynie dewelopera.

Następnie przekazywane są konfiguracje do każdego projektu i uruchamiane są wszystkie projekty jednocześnie.

Proces tworzenia i testowania z Docker i Gitlab CI

Gdyby to graficznie przedstawić, to klientem jest nasza przeglądarka lub jakieś narzędzie, za pomocą którego składamy zapytania do balancera.

Balancer na podstawie nazwy domeny określa, do którego kontenera należy się zwrócić.

To może być nginx, który udostępnia JS panelu administracyjnego. To może być nginx, który udostępnia API lub pliki statyczne, które są serwowane przez nginx jako załadunek obrazków.

Na schemacie widać, że kontenery są połączone wirtualną siecią i ukryte za proxy.

Na maszynie dewelopera można się odwołać do kontenera, znając IP, ale zasadniczo tego nie stosujemy. W praktyce nie ma potrzeby bezpośredniego odwołania.

Proces tworzenia i testowania z Docker i Gitlab CI

Jaki przykład zobaczyć, aby dokeryzować swoje aplikacje? Moim zdaniem dobrym przykładem jest oficjalny obraz docker dla MySQL.

Jest dość skomplikowany. Istnieje wiele wersji. Jednak jego funkcjonalność pozwala zaspokoić wiele potrzeb, które mogą się pojawić w trakcie dalszego rozwoju. Jeśli poświęcisz czas i zrozumiesz, jak to wszystko współdziała, myślę, że w samodzielnym wdrożeniu nie napotkasz problemów.

Na hub.docker.com zazwyczaj znajdują się linki do github.com, gdzie podane są surowe dane, z których można samodzielnie zbudować obraz.

Dalej w tym repozytorium znajduje się skrypt docker-endpoint.sh, który odpowiada za wstępną inicjalizację i dalszą obróbkę uruchamiania aplikacji.

W tym przykładzie znajduje się również możliwość konfigurowania za pomocą zmiennych środowiskowych. Określając zmienną środowiskową przy uruchomieniu pojedynczego kontenera lub przez docker-compose, można powiedzieć, że musimy ustawić puste hasło dla docker dla roota w MySQL lub jakieś, które chcemy.

Istnieje możliwość utworzenia losowego hasła. Mówimy, że potrzebujemy użytkownika, potrzebujemy ustawić hasło dla użytkownika i potrzebujemy stworzyć bazę danych.

W swoich projektach trochę ujednoliciliśmy Dockerfile, który odpowiada za inicjalizację. Dostosowaliśmy go do swoich potrzeb, aby po prostu rozszerzyć uprawnienia użytkownika, które wykorzystuje aplikacja. To pozwoliło nam później po prostu stworzyć bazę danych z konsoli aplikacji. W aplikacjach Ruby istnieje polecenie tworzenia, zmiany i usuwania baz danych.

Proces tworzenia i testowania z Docker i Gitlab CI

Ten przykład pokazuje, jak wygląda konkretna wersja MySQL na github.com. Dockerfile można otworzyć i zobaczyć, jak tam przebiega instalacja.

Skrypt docker-endpoint.sh odpowiada za punkt wejścia. Podczas wstępnej inicjalizacji konieczne są pewne czynności przygotowawcze, a wszystkie te działania są zawarte w skrypcie inicjalizacji.

Proces tworzenia i testowania z Docker i Gitlab CI

Przechodzimy do drugiej części.

Do przechowywania kodu źródłowego przeszliśmy na GitLab. To wystarczająco potężny system, który ma wizualny interfejs.

Jednym z komponentów GitLab jest GitLab CI. Pozwala on opisywać sekwencje poleceń, które później będą wykorzystywane do zorganizowania systemu dostarczania kodu lub uruchamiania testów automatycznych.

Prezentacja na temat GitLab CI 2 https://goo.gl/uohKjI — prezentacja z Ruby Russia club — wystarczająco szczegółowa i być może Cię zainteresuje.

Proces tworzenia i testowania z Docker i Gitlab CI

Teraz przeanalizujemy, co jest wymagane do aktywacji GitLab CI. Aby uruchomić GitLab CI, wystarczy umieścić plik .gitlab-ci.yml w katalogu głównym projektu.

Tutaj opisujemy, co chcemy wykonać w sekwencji stanów typu test, wdrożenie.

Wykonujemy skrypty, które bezpośrednio wywołują komendę docker-compose do budowy naszej aplikacji. To przykład backendu.

Następnie mówimy, że konieczne jest uruchomienie migracji w celu zmiany bazy danych i wykonanie testów.

Jeśli skrypty wykonują się poprawnie i nie zwracają kodu błędu, system przechodzi do drugiej fazy wdrożenia.

Faza wdrożenia jest obecnie realizowana dla staging. Nie zorganizowaliśmy zero-downtime restartu.

Wymuszamy zamknięcie wszystkich kontenerów, a następnie uruchamiamy wszystkie kontenery ponownie, zbudowane na pierwszym etapie podczas testowania.

Uruchamiamy już dla bieżącego środowiska zmiennych migracje baz danych, które zostały napisane przez programistów.

Jest zaznaczenie, aby stosować to tylko dla gałęzi master.

Przy zmianie innych gałęzi nie jest to wykonywane.

Istnieje możliwość organizacji wdrożeń na podstawie gałęzi.

Proces tworzenia i testowania z Docker i Gitlab CI

Aby zorganizować to dalej, musimy zainstalować GitLab Runner.

To narzędzie napisane w Golang. Jest pojedynczym plikiem, co jest typowe w świecie Golang, i nie wymaga żadnych zależności.

Podczas uruchamiania rejestrujemy GitLab Runner.

Otrzymujemy w interfejsie webowym GitLab klucz.

Następnie wywołujemy komendę inicjalizacji w wierszu poleceń.

Konfigurujemy GitLab Runner w trybie dialogowym (Shell, Docker, VirtualBox, SSH)

Kod na GitLab Runner będzie wykonywany przy każdym commitcie w zależności od ustawienia .gitlab-ci.yml.

Proces tworzenia i testowania z Docker i Gitlab CI

Jak to wizualnie wygląda w Gitlab w interfejsie webowym. Po podłączeniu GItlab CI pojawia się flaga, która pokazuje, w jakim stanie jest budowa w danym momencie.

Widzimy, że 4 minuty temu został dokonany commit, który przeszedł wszystkie testy i nie spowodował żadnych problemów.

Proces tworzenia i testowania z Docker i Gitlab CI

Możemy bardziej szczegółowo przyjrzeć się budowom. Tutaj widzimy, że przeszły już dwa stany. Stan testowania i stan wdrożenia na staging.

Jeżeli klikniemy na konkretną budowę, znajdziemy tam wyjście konsoli poleceń, które zostały uruchomione w procesie zgodnie z .gitlab-ci.yml.

Proces tworzenia i testowania z Docker i Gitlab CI

Tak wygląda historia naszego produktu. Widzimy, że były udane próby. Kiedy testy szwankują, to następny krok nie jest wykonywany i kod na staging nie jest aktualizowany.

Proces tworzenia i testowania z Docker i Gitlab CI

Jakie zadania rozwiązywaliśmy na stagingu, gdy wdrażaliśmy Dockera? Nasz system składa się z komponentów i pojawiła się potrzeba ponownego uruchamiania tylko tych komponentów, które zostały zaktualizowane w repozytorium, a nie całego systemu.

W tym celu musieliśmy podzielić wszystko na oddzielne foldery.

Po tym, jak to zrobiliśmy, pojawił się problem, że Docker-compose tworzy dla każdego folderu swoją przestrzeń sieciową i nie widzi komponentów sąsiada.

Aby to obejść, stworzyliśmy sieć w Dockerze ręcznie. W Docker-compose zapisaliśmy, aby używał dla tego projektu takiej sieci.

W ten sposób każdy komponent, który uruchamia się w tej sieci, widzi komponenty w innych częściach systemu.

Następny problem — to podział stagingu między kilka projektów.

Aby wszystko wyglądało estetycznie i maksymalnie zbliżone do produkcji, dobrze jest używać portu 80 lub 443, który jest powszechnie stosowany w sieci WEB.

Proces tworzenia i testowania z Docker i Gitlab CI

Jak to rozwiązaliśmy? Przydzieliliśmy jednego Gitlab Runnera wszystkim większym projektom.

Gitlab pozwala uruchomić kilka rozproszonych Gitlab Runnerów, które będą po kolei w chaotyczny sposób brać wszystkie zadania i je realizować.

Aby uniknąć chaosu, ograniczyliśmy grupę naszych projektów do jednego Gitlab Runnera, który przy naszych wolumenach radzi sobie bez problemów.

Wydzieliliśmy nginx-proxy w osobny skrypt uruchamiania i zapisaliśmy w nim sieci wszystkich projektów.

Nasz projekt ma jedną sieć, a balancer ma kilka sieci po nazwach projektów. Może przekazywać dalej na podstawie nazw domen.

Otrzymujemy zapytania na port 80 na domenę i kierujemy je do grupy kontenerów, która obsługuje tę domenę.

Proces tworzenia i testowania z Docker i Gitlab CI

Jakie inne problemy wystąpiły? Domyślnie wszystkie kontenery działają jako użytkownik root. Ten root nie jest równy rootowi systemu hosta.

Jednak jeśli wejdziemy do kontenera, będziemy mieć dostęp do root, a plik, który tworzymy w tym kontenerze, otrzymuje uprawnienia roota.

Jeżeli deweloper wszedł do kontenera i wykonał tam jakieś polecenia, które generują pliki, a następnie opuścił kontener, to w swoim katalogu roboczym ma plik, do którego nie ma dostępu.

Jak można to rozwiązać? Można dodać użytkowników, którzy będą w kontenerze.

Jakie problemy wystąpiły, gdy dodaliśmy użytkownika?

Tworząc użytkownika, często nie zgadzają się identyfikatory grupy (UID) i identyfikatory użytkownika (GID).

Aby rozwiązać ten problem, w kontenerze używamy użytkowników z ID 1000.

W naszym przypadku zgadza się to z tym, że praktycznie wszyscy deweloperzy używają systemu operacyjnego Ubuntu. W systemie Ubuntu pierwszy użytkownik ma ID 1000.

Proces tworzenia i testowania z Docker i Gitlab CI

Jakie mamy plany?

Przeczytać dokumentację dotyczącą Dockera. Projekt rozwija się, dokumentacja się zmienia. Dane, które zostały zebrane dwa-trzy miesiące temu, już powoli się dezaktualizują.

Część problemów, które rozwiązaliśmy, najprawdopodobniej została już rozwiązana standardowymi środkami.

Tak bardzo chce się iść dalej i przejść bezpośrednio do orkiestracji.

Przykładem jest wbudowany w Docker mechanizm zwany Docker Swarm, który jest dostępny od razu. Chciałbym uruchomić coś w produkcji z użyciem technologii Docker Swarm.

Generowanie kontenerów utrudnia pracę z logami. Obecnie logi są izolowane. Są rozproszone po kontenerach. Jednym z zadań jest zapewnienie wygodnego dostępu do logów za pośrednictwem interfejsu webowego.

Proces tworzenia i testowania z Docker i Gitlab CI

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster