{"id":32526,"date":"2019-10-31T21:47:32","date_gmt":"2019-10-31T18:47:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\/"},"modified":"2019-10-31T21:47:32","modified_gmt":"2019-10-31T18:47:32","slug":"protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","title":{"rendered":"Proces tworzenia i testowania z Docker i Gitlab CI","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Zach\u0119cam do zapoznania si\u0119 z tre\u015bci\u0105 wyst\u0105pienia Aleksandra Sigaczewa z Inventos \u201eProces rozwijania i testowania z Docker + Gitlab CI\u201d<\/strong><\/p>\n<p><\/p>\n<p>Ci, kt\u00f3rzy dopiero zaczynaj\u0105 wdra\u017ca\u0107 proces rozwijania i testowania opartego na Docker + Gitlab CI, cz\u0119sto zadaj\u0105 podstawowe pytania. Od czego zacz\u0105\u0107? Jak to zorganizowa\u0107? Jak testowa\u0107?<\/p>\n<p><\/p>\n<p>Ten referat jest dobry, poniewa\u017c w spos\u00f3b zorganizowany opisuje proces rozwijania i testowania przy u\u017cyciu Docker i Gitlab CI. Sam referat pochodzi z 2017 roku. My\u015bl\u0119, \u017ce mo\u017cna w nim znale\u017a\u0107 podstawy, metodologi\u0119, pomys\u0142y i do\u015bwiadczenie zwi\u0105zane z u\u017cytkowaniem. <\/p>\n<p>\n<center><div class=\"youtube-placeholder\" data-id=\"lJsqRwULRVA\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/lJsqRwULRVA\/hqdefault.jpg\" alt=\"Odtwarzaj wideo\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<p>Kogo to interesuje, zapraszam dalej. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><\/p>\n<p>Nazywam si\u0119 Aleksandr Sigaczew. Pracuj\u0119 w firmie Inventos. Opowiem o swoim do\u015bwiadczeniu z Dockerem i o tym, jak stopniowo wdra\u017camy go w projektach w firmie.<\/p>\n<p><\/p>\n<p>Temat referatu: Proces rozwijania przy u\u017cyciu Docker i Gitlab CI. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e30c4757e4bda1bcc3e20b16e8e2709e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To m\u00f3j drugi referat o Dockerze. W momencie pierwszego wyst\u0105pienia u\u017cywali\u015bmy Dockera tylko w Development na maszynach programist\u00f3w. Liczba pracownik\u00f3w korzystaj\u0105cych z Dockera wynosi\u0142a oko\u0142o 2-3 os\u00f3b. Stopniowo zdobyli\u015bmy do\u015bwiadczenie i posun\u0119li\u015bmy si\u0119 troch\u0119 dalej. Link do naszego <noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/gled\/docker-development-70411088\">pierwszego referatu<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Co b\u0119dzie w tym referacie? Podzielimy si\u0119 do\u015bwiadczeniem, jakie problemy napotkali\u015bmy i jak je rozwi\u0105zali\u015bmy. Nie wsz\u0119dzie by\u0142o to pi\u0119kne, ale pozwoli\u0142o nam i\u015b\u0107 dalej.<\/p>\n<p><\/p>\n<p>Nasze has\u0142o: dockerizuj wszystko, do czego si\u0119gn\u0105 nasze r\u0119ce.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25ae4f97f1c502384abfe697bac502b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jakie problemy rozwi\u0105zujemy?<\/p>\n<p><\/p>\n<p>Kiedy w firmie jest kilka zespo\u0142\u00f3w, programista jest zasobem o wszechstronnym zastosowaniu. Bywaj\u0105 etapy, kiedy programist\u0119 wyci\u0105gaj\u0105 z jednego projektu i przydzielaj\u0105 na troch\u0119 czasu do innego projektu.<\/p>\n<p><\/p>\n<p>Aby programista szybko si\u0119 wprowadzi\u0142, musi pobra\u0107 kod \u017ar\u00f3d\u0142owy projektu i jak najszybciej uruchomi\u0107 \u015brodowisko, kt\u00f3re pozwoli mu kontynuowa\u0107 prac\u0119 nad zadaniami danego projektu.<\/p>\n<p><\/p>\n<p>Zwykle, je\u015bli zaczyna si\u0119 od zera, to dokumentacji w projekcie jest ma\u0142o. Informacje o tym, jak skonfigurowa\u0107, maj\u0105 tylko starzy wyjadacze. Sami pracownicy konfiguruj\u0105 swoje miejsca pracy w ci\u0105gu jednego-dw\u00f3ch dni. Aby to przyspieszy\u0107, zastosowali\u015bmy Dockera.<\/p>\n<p><\/p>\n<p>Nast\u0119pnym powodem jest standaryzacja ustawie\u0144 w Development. Z mojego do\u015bwiadczenia wynika, \u017ce programi\u015bci zawsze wykazuj\u0105 inicjatyw\u0119. W co pi\u0105tym przypadku wprowadza si\u0119 niestandardow\u0105 domen\u0119, na przyk\u0142ad vasya.dev. Obok siedzi s\u0105siad Petya, kt\u00f3ry ma domen\u0119 petya.dev. Tworz\u0105 stron\u0119 lub jaki\u015b komponent systemu, u\u017cywaj\u0105c tej nazwy domeny.<\/p>\n<p><\/p>\n<p>Kiedy system si\u0119 rozrasta, a te domeny zaczynaj\u0105 pojawia\u0107 si\u0119 w konfiguracjach, pojawia si\u0119 konflikt \u015brodowisk Development i zmienia si\u0119 \u015bcie\u017cka do strony.<\/p>\n<p><\/p>\n<p>To samo dotyczy ustawie\u0144 bazy danych. Kto\u015b nie przejmuje si\u0119 bezpiecze\u0144stwem i pracuje z pustym has\u0142em root. Kto\u015b inny podczas instalacji MySQL wymaga\u0142 has\u0142a i mia\u0142 has\u0142o 123. Cz\u0119sto zdarza si\u0119, \u017ce konfiguracja bazy danych zmienia\u0142a si\u0119 w zale\u017cno\u015bci od commit\u00f3w programisty. Kto\u015b poprawi\u0142, kto\u015b nie poprawi\u0142 konfiguracji. By\u0142y sztuczki, kiedy przenosili\u015bmy jak\u0105\u015b testow\u0105 konfiguracj\u0119 do <code>.gitignore<\/code> i ka\u017cdy programista musia\u0142 instalowa\u0107 baz\u0119 danych. To skomplikowa\u0142o proces uruchamiania. Opr\u00f3cz wszystkiego innego nale\u017cy pami\u0119ta\u0107 o bazie danych. Baz\u0119 danych trzeba zainicjowa\u0107, trzeba wpisa\u0107 has\u0142o, trzeba wpisa\u0107 u\u017cytkownika, stworzy\u0107 tabelk\u0119 i tak dalej.<\/p>\n<p><\/p>\n<p>Kolejnym problemem s\u0105 r\u00f3\u017cne wersje bibliotek. Cz\u0119sto zdarza si\u0119, \u017ce programista pracuje z r\u00f3\u017cnymi projektami. Jest projekt Legacy, kt\u00f3ry zacz\u0119to pi\u0119\u0107 lat temu (od 2017 roku \u2013 przyp. red.). Na pocz\u0105tek zacz\u0119to z MySQL 5.5. S\u0105 te\u017c nowoczesne projekty, w kt\u00f3rych staramy si\u0119 wprowadza\u0107 ju\u017c bardziej nowoczesne wersje MySQL, na przyk\u0142ad 5.7 lub starsze (w 2017 roku \u2013 przyp. red.)<\/p>\n<p><\/p>\n<p>Ten, kto pracuje z MySQL, wie, \u017ce te biblioteki poci\u0105gaj\u0105 za sob\u0105 zale\u017cno\u015bci. Dosy\u0107 problematyczne jest uruchomienie 2 baz jednocze\u015bnie. Przynajmniej starych klient\u00f3w problematycznie pod\u0142\u0105czy\u0107 do nowej bazy danych. To z kolei rodzi kilka problem\u00f3w.<\/p>\n<p><\/p>\n<p>Nast\u0119pnym problemem jest sytuacja, gdy programista pracuje na lokalnej maszynie, u\u017cywaj\u0105c lokalnych zasob\u00f3w, lokalnych plik\u00f3w, lokalnej pami\u0119ci RAM. Ca\u0142a interakcja podczas opracowywania rozwi\u0105za\u0144 odbywa si\u0119 w ramach tego, co dzia\u0142a na jednej maszynie. Przyk\u0142adem mo\u017ce by\u0107 sytuacja, gdy mamy 3 serwery backendowe w produkcji, a programista zapisuje pliki w katalogu g\u0142\u00f3wnym, a stamt\u0105d nginx pobiera pliki w odpowiedzi na zapytania. Kiedy taki kod trafia do produkcji, okazuje si\u0119, \u017ce plik znajduje si\u0119 na jednym z 3 serwer\u00f3w.<\/p>\n<p><\/p>\n<p>Obecnie rozwija si\u0119 koncepcja mikroserwis\u00f3w. Dzielimy nasze du\u017ce aplikacje na mniejsze komponenty, kt\u00f3re wzajemnie ze sob\u0105 wsp\u00f3\u0142pracuj\u0105. Umo\u017cliwia to wyb\u00f3r technologii odpowiednich do konkretnego stosu zada\u0144. Dodatkowo pozwala to podzieli\u0107 prac\u0119 i odpowiedzialno\u015b\u0107 mi\u0119dzy programistami.<\/p>\n<p><\/p>\n<p>Frontend-developer, pracuj\u0105c w JS, praktycznie nie wp\u0142ywa na Backend. Backend-developer, w naszym przypadku, rozwija Ruby on Rails i nie przeszkadza Frontendowi. Wsp\u00f3\u0142praca odbywa si\u0119 za pomoc\u0105 API.<\/p>\n<p><\/p>\n<p>Dzi\u0119ki Dockerowi uda\u0142o nam si\u0119 zminimalizowa\u0107 zu\u017cycie zasob\u00f3w na Stagingu. Ka\u017cdy projekt wymaga\u0142 okre\u015blonych ustawie\u0144, w zale\u017cno\u015bci od swojej specyfiki. Fizycznie trzeba by\u0142o albo wydzieli\u0107 po jednym wirtualnym serwerze i osobno je skonfigurowa\u0107, albo podzieli\u0107 jakie\u015b wsp\u00f3lne \u015brodowisko zmienne i projekty mog\u0142y si\u0119 wzajemnie wp\u0142ywa\u0107 w zale\u017cno\u015bci od wersji bibliotek.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/fa5c99f90faef84a356d4791fd915830.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Narz\u0119dzia. Czego u\u017cywamy? <\/p>\n<p><\/p>\n<ul>\n<li>Bezpo\u015brednio sam Docker. W Dockerfile opisane s\u0105 zale\u017cno\u015bci jednego z aplikacji. <\/li>\n<li>Docker-compose to zestawienie, kt\u00f3re \u0142\u0105czy nasze kilka aplikacji Docker.<\/li>\n<li>GitLab u\u017cywamy do przechowywania kodu \u017ar\u00f3d\u0142owego.<\/li>\n<li>GitLab-CI u\u017cywamy do integracji systemowej.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/b6041827a6ba928e0d33add6b79c581c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prezentacja sk\u0142ada si\u0119 z dw\u00f3ch cz\u0119\u015bci.<\/p>\n<p><\/p>\n<p>Pierwsza cz\u0119\u015b\u0107 opowie o tym, jak uruchamiali\u015bmy Dockera na maszynach programist\u00f3w.<\/p>\n<p><\/p>\n<p>Druga cz\u0119\u015b\u0107 opowie o tym, jak wsp\u00f3\u0142pracowa\u0107 z GitLabem, jak uruchamiamy testy i jak wdra\u017camy na Staging.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/45746d3323d35e0d18f066c8bfcb2214.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker to technologia, kt\u00f3ra umo\u017cliwia (stosuj\u0105c podej\u015bcie deklaratywne) opisanie niezb\u0119dnych komponent\u00f3w. Oto przyk\u0142ad Dockerfile. Tutaj og\u0142aszamy, \u017ce dziedziczymy od oficjalnego obrazu Dockera Ruby:2.3.0. Zawiera on zainstalowany Ruby w wersji 2.3. Instalujemy niezb\u0119dne biblioteki do kompilacji oraz NodeJS. Oznajmiamy, \u017ce tworzymy katalog. <code>\/app<\/code>. Ustawiamy katalog app jako bie\u017c\u0105cy katalog roboczy. Umieszczamy w tym katalogu niezb\u0119dny minimalny Gemfile i Gemfile.lock. Nast\u0119pnie wykonujemy budow\u0119 projekt\u00f3w, kt\u00f3re instaluj\u0105 ten obraz zale\u017cno\u015bci. Wskazujemy, \u017ce kontener b\u0119dzie gotowy na nas\u0142uchiwanie na zewn\u0119trznym porcie 3000. Ostatnie polecenie to polecenie, kt\u00f3re bezpo\u015brednio uruchamia nasze aplikacje. Je\u015bli wykonamy polecenie uruchomienia projektu, aplikacja spr\u00f3buje si\u0119 wykona\u0107 i uruchomi podane polecenie.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ba503c305ae90f49b39f4ae2cbda1668.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To minimalny przyk\u0142ad pliku docker-compose. W tym przypadku pokazujemy, jak nast\u0119puje po\u0142\u0105czenie dw\u00f3ch kontener\u00f3w. Chodzi tu o us\u0142ug\u0119 bazy danych oraz us\u0142ug\u0119 web. Nasze aplikacje webowe w wi\u0119kszo\u015bci przypadk\u00f3w wymagaj\u0105 jako backendu pewnej bazy danych do przechowywania informacji. Poniewa\u017c u\u017cywamy MySQL, przyk\u0142ad dotyczy MySQL \u2014 ale nic nie stoi na przeszkodzie, aby u\u017cy\u0107 innej bazy danych (PostgreSQL, Redis).<\/p>\n<p><\/p>\n<p>Bierzemy z oficjalnego \u017ar\u00f3d\u0142a na Docker hub obraz MySQL 5.7.14 bez zmian. Obraz, kt\u00f3ry odpowiada za nasze web aplikacje, budujemy z bie\u017c\u0105cego katalogu. Podczas pierwszego uruchomienia buduje nam obraz. Nast\u0119pnie uruchamia polecenie, kt\u00f3re tutaj wykonujemy. Je\u015bli wr\u00f3cimy krok wstecz, zobaczymy, \u017ce zdefiniowano polecenie uruchomienia przez Puma. Puma to us\u0142uga napisana w Ruby. W drugim przypadku nadpisujemy to. To polecenie mo\u017ce by\u0107 dowolne w zale\u017cno\u015bci od naszych potrzeb lub zada\u0144.<\/p>\n<p><\/p>\n<p>Opisujemy r\u00f3wnie\u017c, \u017ce musimy przekaza\u0107 port na naszej komputerze developerskim z 3000 na 3000 port kontenera. Dzia\u0142a to automatycznie za pomoc\u0105 iptables i swojego mechanizmu, kt\u00f3ry jest bezpo\u015brednio zakodowany w Docker. <\/p>\n<p><\/p>\n<p>Developer mo\u017ce r\u00f3wnie\u017c, jak wcze\u015bniej, zwr\u00f3ci\u0107 si\u0119 do dowolnego dost\u0119pnego adresu IP, na przyk\u0142ad lokalnego 127.0.0.1 lub zewn\u0119trznego adresu IP maszyny.<\/p>\n<p><\/p>\n<p>Ostatnia linijka m\u00f3wi, \u017ce kontener web zale\u017cy od kontenera db. Kiedy uruchamiamy kontener web, wcze\u015bniej docker-compose uruchomi dla nas baz\u0119 danych. Ju\u017c po starcie bazy danych (w rzeczywisto\u015bci \u2014 po uruchomieniu kontenera! Gotowo\u015b\u0107 Bazy Danych tego nie gwarantuje) uruchomi nam aplikacj\u0119, nasz backend.<\/p>\n<p><\/p>\n<p>Pozwala to unikn\u0105\u0107 b\u0142\u0119d\u00f3w, gdy baza danych nie jest uruchomiona i oszcz\u0119dza zasoby, gdy zatrzymujemy kontener bazy danych, zwalniaj\u0105c tym samym zasoby na inne projekty. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4acbcf5de89b98db055e8abc419202de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co nam daje u\u017cywanie dokeryzacji bazy danych w projekcie. Rejestrujemy u wszystkich deweloper\u00f3w wersj\u0119 MySQL. Pozwala to unikn\u0105\u0107 niekt\u00f3rych b\u0142\u0119d\u00f3w, kt\u00f3re mog\u0105 wyst\u0105pi\u0107 w przypadku r\u00f3\u017cnic wersji, gdy zmienia si\u0119 sk\u0142adnia, konfiguracja, domy\u015blne ustawienia. Umo\u017cliwia to wskazanie wsp\u00f3lnego hostname dla bazy danych, loginu, has\u0142a. Odchodzimy od tego zoo nazw i konflikt\u00f3w w plikach konfiguracyjnych, kt\u00f3re by\u0142y wcze\u015bniej. <\/p>\n<p><\/p>\n<p>Mamy mo\u017cliwo\u015b\u0107 u\u017cycia bardziej optymalnej konfiguracji dla \u015brodowiska deweloperskiego, kt\u00f3ra b\u0119dzie r\u00f3\u017cni\u0107 si\u0119 od domy\u015blnej. MySQL domy\u015blnie jest skonfigurowany do pracy na s\u0142abych maszynach i jego wydajno\u015b\u0107 z pude\u0142ka jest bardzo niska.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/417d77a06b18e2df9b71440c0f2a1653.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker pozwala korzysta\u0107 z interpreter\u00f3w Python, Ruby, NodeJS, PHP w potrzebnych wersjach. Uwalniamy si\u0119 od konieczno\u015bci stosowania mened\u017cera wersji. W przesz\u0142o\u015bci dla Ruby u\u017cywano pakiet\u00f3w rpm, kt\u00f3re pozwala\u0142y zmienia\u0107 wersj\u0119 w zale\u017cno\u015bci od projektu. Pozwala to dzi\u0119ki kontenerom Docker p\u0142ynnie migrowa\u0107 kod i wersjonowa\u0107 go razem z zale\u017cno\u015bciami. Nie mamy problemu ze zrozumieniem wersji zar\u00f3wno interpretera, jak i kodu. Aby zaktualizowa\u0107 wersj\u0119, nale\u017cy usun\u0105\u0107 stary kontener i uruchomi\u0107 nowy kontener. Je\u015bli co\u015b p\u00f3jdzie nie tak, mo\u017cemy usun\u0105\u0107 nowy kontener, uruchomi\u0107 stary kontener.<\/p>\n<p><\/p>\n<p>Po zbudowaniu obrazu kontenery zar\u00f3wno w \u015brodowisku deweloperskim, jak i produkcyjnym b\u0119d\u0105 identyczne. Jest to szczeg\u00f3lnie istotne w przypadku du\u017cych instalacji.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/185a1bfe257f7e3e0eecdc6e0e0d330f.jpg\" style=\"display:block;margin: 0 auto;\" \/> Na Frontendzie u\u017cywamy JavaScript i NodeJS.<\/p>\n<p><\/p>\n<p>Obecnie nasz ostatni projekt oparty jest na ReacJS. Deweloper uruchamia\u0142 wszystkie kontenery i rozwija\u0142 projekt u\u017cywaj\u0105c hot-reload.<\/p>\n<p><\/p>\n<p>Nast\u0119pnie uruchamiana jest zadanie kompilacji JavaScript, a skompilowany kod w postaci statyki jest przekazywany przez nginx, oszcz\u0119dzaj\u0105c zasoby.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4c2e28319d56d7fc81845b4133a1bfe6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W tym miejscu przedstawi\u0142em schemat naszego ostatniego projektu.<\/p>\n<p><\/p>\n<p>Jakie zadania zosta\u0142y rozwi\u0105zane? Mieli\u015bmy potrzeb\u0119 zbudowania systemu, z kt\u00f3rym wsp\u00f3\u0142pracuj\u0105 urz\u0105dzenia mobilne. Odbieraj\u0105 dane. Jedn\u0105 z mo\u017cliwo\u015bci jest wys\u0142anie powiadomie\u0144 push do danego urz\u0105dzenia. <\/p>\n<p><\/p>\n<p>Co zrobili\u015bmy w tym celu?<\/p>\n<p><\/p>\n<p>Podzielili\u015bmy aplikacj\u0119 na takie komponenty jak: cz\u0119\u015b\u0107 administracyjna na JS, backend, kt\u00f3ry dzia\u0142a przez interfejs REST w Ruby on Rails. Backend wsp\u00f3\u0142pracuje z baz\u0105 danych. Wynik, kt\u00f3ry jest generowany, jest przekazywany klientowi. Panel administracyjny z backendem i baz\u0105 danych wsp\u00f3\u0142pracuje przez interfejs REST.<\/p>\n<p><\/p>\n<p>Mieli\u015bmy r\u00f3wnie\u017c potrzeb\u0119 wysy\u0142ania powiadomie\u0144 Push. Wcze\u015bniej mieli\u015bmy projekt, w kt\u00f3rym wdro\u017cono mechanizm odpowiedzialny za dostarczanie powiadomie\u0144 na platformy mobilne. <\/p>\n<p><\/p>\n<p>Opracowali\u015bmy taki schemat: operator w przegl\u0105darce interaguje z panelem administracyjnym, panel administracyjny interaguje z backendem, a nast\u0119pnie zostaje zlecone wys\u0142anie powiadomie\u0144 Push.<\/p>\n<p><\/p>\n<p>Powiadomienia Push wsp\u00f3\u0142dzia\u0142aj\u0105 z innym komponentem, kt\u00f3ry zosta\u0142 wdro\u017cony na NodeJS.<\/p>\n<p><\/p>\n<p>Tworzone s\u0105 kolejki, a nast\u0119pnie nast\u0119puje wysy\u0142ka powiadomie\u0144 wed\u0142ug w\u0142asnego mechanizmu.<\/p>\n<p><\/p>\n<p>Tutaj przedstawione s\u0105 dwie bazy danych. Obecnie u\u017cywamy przy pomocy Docker dw\u00f3ch niezale\u017cnych baz danych, kt\u00f3re nie s\u0105 ze sob\u0105 powi\u0105zane. Opr\u00f3cz tego maj\u0105 wsp\u00f3ln\u0105 sie\u0107 wirtualn\u0105, a fizyczne dane przechowywane s\u0105 w r\u00f3\u017cnych katalogach na komputerze programisty.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/dfde59db7e6886d2d851dcf884049318.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To samo, ale w liczbach. Wa\u017cne jest tutaj ponowne wykorzystanie kodu.<\/p>\n<p><\/p>\n<p>Je\u015bli wcze\u015bniej m\u00f3wili\u015bmy o ponownym wykorzystaniu kodu w postaci bibliotek, to w tym przypadku nasza us\u0142uga odpowiedzialna za powiadomienia Push jest wykorzystywana jako pe\u0142ny serwer. Oferuje API, z kt\u00f3rym interaguje nasza nowa aplikacja.<\/p>\n<p><\/p>\n<p>W tamtym czasie u\u017cywali\u015bmy wersji 4 NodeJS. Teraz (w 2017 roku \u2014 przypis red.) w nowych projektach u\u017cywamy wersji 7 NodeJS. Nie ma problem\u00f3w z u\u017cywaniem nowych wersji bibliotek w nowych komponentach. <\/p>\n<p><\/p>\n<p>W razie potrzeby mo\u017cna przeprowadzi\u0107 refaktoryzacj\u0119 i podnie\u015b\u0107 wersj\u0119 NodeJS w us\u0142udze powiadomie\u0144 Push. <\/p>\n<p><\/p>\n<p>A je\u015bli b\u0119dziemy mogli zachowa\u0107 zgodno\u015b\u0107 API, mo\u017cna b\u0119dzie j\u0105 wymieni\u0107 na innych projektach, kt\u00f3re by\u0142y wcze\u015bniej u\u017cywane.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5c58c65be078a5a1b9fc17ee2e7b4ad4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co jest potrzebne aby doda\u0107 Docker? Dodajemy do naszego repozytorium Dockerfile, kt\u00f3ry opisuje niezb\u0119dne zale\u017cno\u015bci. W tym przyk\u0142adzie komponenty s\u0105 podzielone wed\u0142ug logiki. To minimalny zestaw dla backend-developera.<\/p>\n<p><\/p>\n<p>Podczas tworzenia nowego projektu tworzymy Dockerfile, opisujemy potrzebny ekosystem (Python, Ruby, NodeJS). W pliku docker-compose opisujemy niezb\u0119dn\u0105 zale\u017cno\u015b\u0107 \u2014 baz\u0119 danych. Opisujemy, \u017ce potrzebna jest baza okre\u015blonej wersji, by przechowywa\u0107 dane tam, gdzie jest to wymagane.<\/p>\n<p><\/p>\n<p>U\u017cywamy osobnego trzeciego kontenera z nginx do wydawania statycznych zasob\u00f3w. Przewidziano mo\u017cliwo\u015b\u0107 przesy\u0142ania obrazk\u00f3w. Backend umieszcza je w wcze\u015bniej przygotowanej obj\u0119to\u015bci, kt\u00f3ra jest r\u00f3wnie\u017c zamontowana w kontenerze z nginx, kt\u00f3ry wydaje statyk\u0119.<\/p>\n<p><\/p>\n<p>Aby przechowa\u0107 konfiguracj\u0119 nginx, mysql, dodali\u015bmy folder Docker, w kt\u00f3rym przechowujemy niezb\u0119dne konfiguracje. Kiedy deweloper klonuje repozytorium na swoj\u0105 maszyn\u0119, otrzymuje ju\u017c projekt gotowy do lokalnego rozwoju. Nie ma pytania, jaki port lub jakie ustawienia zastosowa\u0107.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e7a6b308a75cacf8ce60687a9e6081dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dalej mamy kilka komponent\u00f3w: admin, inform-API, powiadomienia push.<\/p>\n<p><\/p>\n<p>Aby uruchomi\u0107 to wszystko, stworzyli\u015bmy kolejne repozytorium, kt\u00f3re nazwali\u015bmy dockerized-app. Na chwil\u0119 obecn\u0105 korzystamy z kilku repozytori\u00f3w dla ka\u017cdego komponentu. R\u00f3\u017cni\u0105 si\u0119 one tylko logicznie \u2014 w GitLab wygl\u0105da to jak folder, a na maszynie dewelopera jako folder pod konkretny projekt. Na ni\u017cszym poziomie znajduj\u0105 si\u0119 komponenty, kt\u00f3re b\u0119d\u0105 scalane.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f4e2c45c8ec20fca0bac74b3a3892543.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To jest przyk\u0142ad zawarto\u015bci dockerized-app. Wyci\u0105gamy tutaj r\u00f3wnie\u017c katalog Docker, w kt\u00f3rym umieszczamy konfiguracje potrzebne do interakcji wszystkich komponent\u00f3w. Jest README.md, w kt\u00f3rym kr\u00f3tko opisano, jak uruchomi\u0107 projekt.<\/p>\n<p><\/p>\n<p>Zastosowali\u015bmy tutaj dwa pliki docker-compose. Zrobiono to, aby mie\u0107 mo\u017cliwo\u015b\u0107 uruchamiania stopniowo. Kiedy deweloper pracuje z rdzeniem, nie potrzebuje powiadomie\u0144 push, wi\u0119c uruchamia tylko plik docker-compose, co w efekcie oszcz\u0119dza zasoby.<\/p>\n<p><\/p>\n<p>Je\u015bli zachodzi potrzeba integracji z powiadomieniami push, uruchamiany jest docker-compose.yaml i docker-compose-push.yaml.<\/p>\n<p><\/p>\n<p>Poniewa\u017c docker-compose.yaml i docker-compose-push.yaml znajduj\u0105 si\u0119 w folderze, automatycznie tworzy si\u0119 jedna wirtualna sie\u0107.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/535019c82c72c1602176fbaf4aa5640f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Opis komponent\u00f3w. To bardziej rozwini\u0119ty plik, kt\u00f3ry odpowiada za zbieranie komponent\u00f3w. Co tutaj jest istotne? Wprowadzamy komponent balancer.<\/p>\n<p><\/p>\n<p>To gotowy obraz Docker, w kt\u00f3rym uruchamiany jest nginx i aplikacja, kt\u00f3ra nas\u0142uchuje na sockecie Docker. Dynamicznie, w miar\u0119 w\u0142\u0105czania i wy\u0142\u0105czania kontener\u00f3w, regeneruje konfiguracj\u0119 nginx. Obs\u0142uga komponent\u00f3w jest rozdzielana po nazwach domen trzeciego poziomu.<\/p>\n<p><\/p>\n<p>Dla \u015brodowiska rozwojowego u\u017cywamy domeny .dev \u2014 api.informer.dev. Aplikacje z domen\u0105 .dev s\u0105 dost\u0119pne na lokalnej maszynie dewelopera.<\/p>\n<p><\/p>\n<p>Nast\u0119pnie przekazywane s\u0105 konfiguracje do ka\u017cdego projektu i uruchamiane s\u0105 wszystkie projekty jednocze\u015bnie.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/bc1e11e6f1fd1c837d2c8087d04145c4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Gdyby to graficznie przedstawi\u0107, to klientem jest nasza przegl\u0105darka lub jakie\u015b narz\u0119dzie, za pomoc\u0105 kt\u00f3rego sk\u0142adamy zapytania do balancera.<\/p>\n<p><\/p>\n<p>Balancer na podstawie nazwy domeny okre\u015bla, do kt\u00f3rego kontenera nale\u017cy si\u0119 zwr\u00f3ci\u0107.<\/p>\n<p><\/p>\n<p>To mo\u017ce by\u0107 nginx, kt\u00f3ry udost\u0119pnia JS panelu administracyjnego. To mo\u017ce by\u0107 nginx, kt\u00f3ry udost\u0119pnia API lub pliki statyczne, kt\u00f3re s\u0105 serwowane przez nginx jako za\u0142adunek obrazk\u00f3w.<\/p>\n<p><\/p>\n<p>Na schemacie wida\u0107, \u017ce kontenery s\u0105 po\u0142\u0105czone wirtualn\u0105 sieci\u0105 i ukryte za proxy.<\/p>\n<p><\/p>\n<p>Na maszynie dewelopera mo\u017cna si\u0119 odwo\u0142a\u0107 do kontenera, znaj\u0105c IP, ale zasadniczo tego nie stosujemy. W praktyce nie ma potrzeby bezpo\u015bredniego odwo\u0142ania.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/2908c31fd9d3c79f6189bdbeeb6d028f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jaki przyk\u0142ad zobaczy\u0107, aby dokeryzowa\u0107 swoje aplikacje? Moim zdaniem dobrym przyk\u0142adem jest oficjalny obraz docker dla MySQL.<\/p>\n<p><\/p>\n<p>Jest do\u015b\u0107 skomplikowany. Istnieje wiele wersji. Jednak jego funkcjonalno\u015b\u0107 pozwala zaspokoi\u0107 wiele potrzeb, kt\u00f3re mog\u0105 si\u0119 pojawi\u0107 w trakcie dalszego rozwoju. Je\u015bli po\u015bwi\u0119cisz czas i zrozumiesz, jak to wszystko wsp\u00f3\u0142dzia\u0142a, my\u015bl\u0119, \u017ce w samodzielnym wdro\u017ceniu nie napotkasz problem\u00f3w.<\/p>\n<p><\/p>\n<p>Na hub.docker.com zazwyczaj znajduj\u0105 si\u0119 linki do github.com, gdzie podane s\u0105 surowe dane, z kt\u00f3rych mo\u017cna samodzielnie zbudowa\u0107 obraz.<\/p>\n<p><\/p>\n<p>Dalej w tym repozytorium znajduje si\u0119 skrypt docker-endpoint.sh, kt\u00f3ry odpowiada za wst\u0119pn\u0105 inicjalizacj\u0119 i dalsz\u0105 obr\u00f3bk\u0119 uruchamiania aplikacji.<\/p>\n<p><\/p>\n<p>W tym przyk\u0142adzie znajduje si\u0119 r\u00f3wnie\u017c mo\u017cliwo\u015b\u0107 konfigurowania za pomoc\u0105 zmiennych \u015brodowiskowych. Okre\u015blaj\u0105c zmienn\u0105 \u015brodowiskow\u0105 przy uruchomieniu pojedynczego kontenera lub przez docker-compose, mo\u017cna powiedzie\u0107, \u017ce musimy ustawi\u0107 puste has\u0142o dla docker dla roota w MySQL lub jakie\u015b, kt\u00f3re chcemy.<\/p>\n<p><\/p>\n<p>Istnieje mo\u017cliwo\u015b\u0107 utworzenia losowego has\u0142a. M\u00f3wimy, \u017ce potrzebujemy u\u017cytkownika, potrzebujemy ustawi\u0107 has\u0142o dla u\u017cytkownika i potrzebujemy stworzy\u0107 baz\u0119 danych.<\/p>\n<p><\/p>\n<p>W swoich projektach troch\u0119 ujednolicili\u015bmy Dockerfile, kt\u00f3ry odpowiada za inicjalizacj\u0119. Dostosowali\u015bmy go do swoich potrzeb, aby po prostu rozszerzy\u0107 uprawnienia u\u017cytkownika, kt\u00f3re wykorzystuje aplikacja. To pozwoli\u0142o nam p\u00f3\u017aniej po prostu stworzy\u0107 baz\u0119 danych z konsoli aplikacji. W aplikacjach Ruby istnieje polecenie tworzenia, zmiany i usuwania baz danych.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4a9b56e21819d28dd39753134d23fee4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ten przyk\u0142ad pokazuje, jak wygl\u0105da konkretna wersja MySQL na github.com. Dockerfile mo\u017cna otworzy\u0107 i zobaczy\u0107, jak tam przebiega instalacja.<\/p>\n<p><\/p>\n<p>Skrypt docker-endpoint.sh odpowiada za punkt wej\u015bcia. Podczas wst\u0119pnej inicjalizacji konieczne s\u0105 pewne czynno\u015bci przygotowawcze, a wszystkie te dzia\u0142ania s\u0105 zawarte w skrypcie inicjalizacji.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4153fa46526f3d802931dd1db48b08cd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Przechodzimy do drugiej cz\u0119\u015bci.<\/p>\n<p><\/p>\n<p>Do przechowywania kodu \u017ar\u00f3d\u0142owego przeszli\u015bmy na GitLab. To wystarczaj\u0105co pot\u0119\u017cny system, kt\u00f3ry ma wizualny interfejs.<\/p>\n<p><\/p>\n<p>Jednym z komponent\u00f3w GitLab jest GitLab CI. Pozwala on opisywa\u0107 sekwencje polece\u0144, kt\u00f3re p\u00f3\u017aniej b\u0119d\u0105 wykorzystywane do zorganizowania systemu dostarczania kodu lub uruchamiania test\u00f3w automatycznych.<\/p>\n<p><\/p>\n<p>Prezentacja na temat GitLab CI 2 <noindex><a rel=\"nofollow\" href=\"https:\/\/goo.gl\/uohKjI\">https:\/\/goo.gl\/uohKjI<\/a><\/noindex> \u2014 prezentacja z Ruby Russia club \u2014 wystarczaj\u0105co szczeg\u00f3\u0142owa i by\u0107 mo\u017ce Ci\u0119 zainteresuje.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5d26d20500f34eeb9768e6c3d91bbefa.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Teraz przeanalizujemy, co jest wymagane do aktywacji GitLab CI. Aby uruchomi\u0107 GitLab CI, wystarczy umie\u015bci\u0107 plik .gitlab-ci.yml w katalogu g\u0142\u00f3wnym projektu.<\/p>\n<p><\/p>\n<p>Tutaj opisujemy, co chcemy wykona\u0107 w sekwencji stan\u00f3w typu test, wdro\u017cenie.<\/p>\n<p><\/p>\n<p>Wykonujemy skrypty, kt\u00f3re bezpo\u015brednio wywo\u0142uj\u0105 komend\u0119 docker-compose do budowy naszej aplikacji. To przyk\u0142ad backendu.<\/p>\n<p><\/p>\n<p>Nast\u0119pnie m\u00f3wimy, \u017ce konieczne jest uruchomienie migracji w celu zmiany bazy danych i wykonanie test\u00f3w.<\/p>\n<p><\/p>\n<p>Je\u015bli skrypty wykonuj\u0105 si\u0119 poprawnie i nie zwracaj\u0105 kodu b\u0142\u0119du, system przechodzi do drugiej fazy wdro\u017cenia.<\/p>\n<p><\/p>\n<p>Faza wdro\u017cenia jest obecnie realizowana dla staging. Nie zorganizowali\u015bmy zero-downtime restartu.<\/p>\n<p><\/p>\n<p>Wymuszamy zamkni\u0119cie wszystkich kontener\u00f3w, a nast\u0119pnie uruchamiamy wszystkie kontenery ponownie, zbudowane na pierwszym etapie podczas testowania.<\/p>\n<p><\/p>\n<p>Uruchamiamy ju\u017c dla bie\u017c\u0105cego \u015brodowiska zmiennych migracje baz danych, kt\u00f3re zosta\u0142y napisane przez programist\u00f3w.<\/p>\n<p><\/p>\n<p>Jest zaznaczenie, aby stosowa\u0107 to tylko dla ga\u0142\u0119zi master.<\/p>\n<p><\/p>\n<p>Przy zmianie innych ga\u0142\u0119zi nie jest to wykonywane.<\/p>\n<p><\/p>\n<p>Istnieje mo\u017cliwo\u015b\u0107 organizacji wdro\u017ce\u0144 na podstawie ga\u0142\u0119zi.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/8a5b880bd9a0d4bab0b276568e2ba413.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aby zorganizowa\u0107 to dalej, musimy zainstalowa\u0107 GitLab Runner.<\/p>\n<p><\/p>\n<p>To narz\u0119dzie napisane w Golang. Jest pojedynczym plikiem, co jest typowe w \u015bwiecie Golang, i nie wymaga \u017cadnych zale\u017cno\u015bci.<\/p>\n<p><\/p>\n<p>Podczas uruchamiania rejestrujemy GitLab Runner.<\/p>\n<p><\/p>\n<p>Otrzymujemy w interfejsie webowym GitLab klucz.<\/p>\n<p><\/p>\n<p>Nast\u0119pnie wywo\u0142ujemy komend\u0119 inicjalizacji w wierszu polece\u0144.<\/p>\n<p><\/p>\n<p>Konfigurujemy GitLab Runner w trybie dialogowym (Shell, Docker, VirtualBox, SSH)<\/p>\n<p><\/p>\n<p>Kod na GitLab Runner b\u0119dzie wykonywany przy ka\u017cdym commitcie w zale\u017cno\u015bci od ustawienia .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/37c8ac7499f0cfba2eb07a84083e44e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak to wizualnie wygl\u0105da w Gitlab w interfejsie webowym. Po pod\u0142\u0105czeniu GItlab CI pojawia si\u0119 flaga, kt\u00f3ra pokazuje, w jakim stanie jest budowa w danym momencie.<\/p>\n<p><\/p>\n<p>Widzimy, \u017ce 4 minuty temu zosta\u0142 dokonany commit, kt\u00f3ry przeszed\u0142 wszystkie testy i nie spowodowa\u0142 \u017cadnych problem\u00f3w.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/33ac79c45f0651a5f8bde75092c4ac44.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mo\u017cemy bardziej szczeg\u00f3\u0142owo przyjrze\u0107 si\u0119 budowom. Tutaj widzimy, \u017ce przesz\u0142y ju\u017c dwa stany. Stan testowania i stan wdro\u017cenia na staging.<\/p>\n<p><\/p>\n<p>Je\u017celi klikniemy na konkretn\u0105 budow\u0119, znajdziemy tam wyj\u015bcie konsoli polece\u0144, kt\u00f3re zosta\u0142y uruchomione w procesie zgodnie z .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d26dd28708c7fc8a409af4be4d48f502.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tak wygl\u0105da historia naszego produktu. Widzimy, \u017ce by\u0142y udane pr\u00f3by. Kiedy testy szwankuj\u0105, to nast\u0119pny krok nie jest wykonywany i kod na staging nie jest aktualizowany.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ee7bd81dc283c7af0c194779d4230780.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jakie zadania rozwi\u0105zywali\u015bmy na stagingu, gdy wdra\u017cali\u015bmy Dockera? Nasz system sk\u0142ada si\u0119 z komponent\u00f3w i pojawi\u0142a si\u0119 potrzeba ponownego uruchamiania tylko tych komponent\u00f3w, kt\u00f3re zosta\u0142y zaktualizowane w repozytorium, a nie ca\u0142ego systemu.<\/p>\n<p><\/p>\n<p>W tym celu musieli\u015bmy podzieli\u0107 wszystko na oddzielne foldery.<\/p>\n<p><\/p>\n<p>Po tym, jak to zrobili\u015bmy, pojawi\u0142 si\u0119 problem, \u017ce Docker-compose tworzy dla ka\u017cdego folderu swoj\u0105 przestrze\u0144 sieciow\u0105 i nie widzi komponent\u00f3w s\u0105siada.<\/p>\n<p><\/p>\n<p>Aby to obej\u015b\u0107, stworzyli\u015bmy sie\u0107 w Dockerze r\u0119cznie. W Docker-compose zapisali\u015bmy, aby u\u017cywa\u0142 dla tego projektu takiej sieci.<\/p>\n<p><\/p>\n<p>W ten spos\u00f3b ka\u017cdy komponent, kt\u00f3ry uruchamia si\u0119 w tej sieci, widzi komponenty w innych cz\u0119\u015bciach systemu.<\/p>\n<p><\/p>\n<p>Nast\u0119pny problem \u2014 to podzia\u0142 stagingu mi\u0119dzy kilka projekt\u00f3w.<\/p>\n<p><\/p>\n<p>Aby wszystko wygl\u0105da\u0142o estetycznie i maksymalnie zbli\u017cone do produkcji, dobrze jest u\u017cywa\u0107 portu 80 lub 443, kt\u00f3ry jest powszechnie stosowany w sieci WEB.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f863cf1833271bf132455a70ad7d2706.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak to rozwi\u0105zali\u015bmy? Przydzielili\u015bmy jednego Gitlab Runnera wszystkim wi\u0119kszym projektom.<\/p>\n<p><\/p>\n<p>Gitlab pozwala uruchomi\u0107 kilka rozproszonych Gitlab Runner\u00f3w, kt\u00f3re b\u0119d\u0105 po kolei w chaotyczny spos\u00f3b bra\u0107 wszystkie zadania i je realizowa\u0107.<\/p>\n<p><\/p>\n<p>Aby unikn\u0105\u0107 chaosu, ograniczyli\u015bmy grup\u0119 naszych projekt\u00f3w do jednego Gitlab Runnera, kt\u00f3ry przy naszych wolumenach radzi sobie bez problem\u00f3w.<\/p>\n<p><\/p>\n<p>Wydzielili\u015bmy nginx-proxy w osobny skrypt uruchamiania i zapisali\u015bmy w nim sieci wszystkich projekt\u00f3w. <\/p>\n<p><\/p>\n<p>Nasz projekt ma jedn\u0105 sie\u0107, a balancer ma kilka sieci po nazwach projekt\u00f3w. Mo\u017ce przekazywa\u0107 dalej na podstawie nazw domen.<\/p>\n<p><\/p>\n<p>Otrzymujemy zapytania na port 80 na domen\u0119 i kierujemy je do grupy kontener\u00f3w, kt\u00f3ra obs\u0142uguje t\u0119 domen\u0119.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25c769f029b272a17fd06bbe60cf0ea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jakie inne problemy wyst\u0105pi\u0142y? Domy\u015blnie wszystkie kontenery dzia\u0142aj\u0105 jako u\u017cytkownik root. Ten root nie jest r\u00f3wny rootowi systemu hosta.<\/p>\n<p><\/p>\n<p>Jednak je\u015bli wejdziemy do kontenera, b\u0119dziemy mie\u0107 dost\u0119p do root, a plik, kt\u00f3ry tworzymy w tym kontenerze, otrzymuje uprawnienia roota.<\/p>\n<p><\/p>\n<p>Je\u017celi deweloper wszed\u0142 do kontenera i wykona\u0142 tam jakie\u015b polecenia, kt\u00f3re generuj\u0105 pliki, a nast\u0119pnie opu\u015bci\u0142 kontener, to w swoim katalogu roboczym ma plik, do kt\u00f3rego nie ma dost\u0119pu.<\/p>\n<p><\/p>\n<p>Jak mo\u017cna to rozwi\u0105za\u0107? Mo\u017cna doda\u0107 u\u017cytkownik\u00f3w, kt\u00f3rzy b\u0119d\u0105 w kontenerze.<\/p>\n<p><\/p>\n<p>Jakie problemy wyst\u0105pi\u0142y, gdy dodali\u015bmy u\u017cytkownika?<\/p>\n<p><\/p>\n<p>Tworz\u0105c u\u017cytkownika, cz\u0119sto nie zgadzaj\u0105 si\u0119 identyfikatory grupy (UID) i identyfikatory u\u017cytkownika (GID).<\/p>\n<p><\/p>\n<p>Aby rozwi\u0105za\u0107 ten problem, w kontenerze u\u017cywamy u\u017cytkownik\u00f3w z ID 1000.<\/p>\n<p><\/p>\n<p>W naszym przypadku zgadza si\u0119 to z tym, \u017ce praktycznie wszyscy deweloperzy u\u017cywaj\u0105 systemu operacyjnego Ubuntu. W systemie Ubuntu pierwszy u\u017cytkownik ma ID 1000.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d4911374e4953fdcd807c387efeafec3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jakie mamy plany?<\/p>\n<p><\/p>\n<p>Przeczyta\u0107 dokumentacj\u0119 dotycz\u0105c\u0105 Dockera. Projekt rozwija si\u0119, dokumentacja si\u0119 zmienia. Dane, kt\u00f3re zosta\u0142y zebrane dwa-trzy miesi\u0105ce temu, ju\u017c powoli si\u0119 dezaktualizuj\u0105. <\/p>\n<p><\/p>\n<p>Cz\u0119\u015b\u0107 problem\u00f3w, kt\u00f3re rozwi\u0105zali\u015bmy, najprawdopodobniej zosta\u0142a ju\u017c rozwi\u0105zana standardowymi \u015brodkami.<\/p>\n<p><\/p>\n<p>Tak bardzo chce si\u0119 i\u015b\u0107 dalej i przej\u015b\u0107 bezpo\u015brednio do orkiestracji.<\/p>\n<p><\/p>\n<p>Przyk\u0142adem jest wbudowany w Docker mechanizm zwany Docker Swarm, kt\u00f3ry jest dost\u0119pny od razu. Chcia\u0142bym uruchomi\u0107 co\u015b w produkcji z u\u017cyciem technologii Docker Swarm.<\/p>\n<p><\/p>\n<p>Generowanie kontener\u00f3w utrudnia prac\u0119 z logami. Obecnie logi s\u0105 izolowane. S\u0105 rozproszone po kontenerach. Jednym z zada\u0144 jest zapewnienie wygodnego dost\u0119pu do log\u00f3w za po\u015brednictwem interfejsu webowego.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces tworzenia i testowania z Docker i Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/cff8c72dd8af7de1fa0227601bd1d69c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/449742\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &#171;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&#187; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 Docker + Gitlab CI \u0447\u0430\u0441\u0442\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b. \u0421 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c? \u041a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c? \u041a\u0430\u043a \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c? \u042d\u0442\u043e\u0442 \u0434\u043e\u043a\u043b\u0430\u0434 \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24326,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker \u0438 Gitlab CI | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:47:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:47:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Proces tworzenia i testowania z Docker i Gitlab CI | ProHoster","description":"Zach\u0119cam do zapoznania si\u0119 z transkrypcj\u0105 raportu Aleksandra Sigaczewa z Inventos \"Proces opracowywania i testowania z Docker + Gitlab CI\". Ci, kt\u00f3rzy dopiero zaczynaj\u0105 wdra\u017ca\u0107 proces rozwoju i.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker \u0438 Gitlab CI | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0421\u0438\u0433\u0430\u0447\u0435\u0432\u0430 \u0438\u0437 Inventos &quot;\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Docker + Gitlab CI&quot; \u0422\u0435, \u043a\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:47:32+00:00","article:modified_time":"2019-10-31T18:47:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32526","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 11:18:24","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:57:22","updated":"2026-01-21 11:18:24","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/32526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=32526"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/32526\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/24326"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=32526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=32526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=32526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}