{"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\/cs\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","title":{"rendered":"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Doporu\u010duji se sezn\u00e1mit s p\u0159episem zpr\u00e1vy Alexandra Sigacheva z Inventos \u201eProces v\u00fdvoje a testov\u00e1n\u00ed s Dockerem + Gitlab CI\u201c<\/strong><\/p>\n<p><\/p>\n<p>Ti, kdo pr\u00e1v\u011b za\u010d\u00ednaj\u00ed zav\u00e1d\u011bt proces v\u00fdvoje a testov\u00e1n\u00ed na b\u00e1zi Docker + Gitlab CI, se \u010dasto ptaj\u00ed na z\u00e1kladn\u00ed ot\u00e1zky. Odkud za\u010d\u00edt? Jak to uspo\u0159\u00e1dat? Jak testovat?<\/p>\n<p><\/p>\n<p>Tato zpr\u00e1va je dobr\u00e1 t\u00edm, \u017ee strukturovan\u011b popisuje proces v\u00fdvoje a testov\u00e1n\u00ed s vyu\u017eit\u00edm Docker a Gitlab CI. Samotn\u00e1 zpr\u00e1va je z roku 2017. Mysl\u00edm, \u017ee z t\u00e9to zpr\u00e1vy lze odvodit z\u00e1klady, metodologii, my\u0161lenku a zku\u0161enosti z pou\u017e\u00edv\u00e1n\u00ed. <\/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=\"P\u0159ehr\u00e1t video\" 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>Kdo m\u00e1 z\u00e1jem, pros\u00edm, pokra\u010dujte d\u00e1l. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><\/p>\n<p>Jmenuji se Alexander Sigachev. Pracuji ve spole\u010dnosti Inventos. Pod\u011bl\u00edm se o sv\u00e9 zku\u0161enosti s pou\u017e\u00edv\u00e1n\u00edm Dockeru a o tom, jak ho postupn\u011b zav\u00e1d\u00edme do projekt\u016f ve firm\u011b.<\/p>\n<p><\/p>\n<p>T\u00e9ma zpr\u00e1vy: Proces v\u00fdvoje s vyu\u017eit\u00edm Docker a Gitlab CI. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e30c4757e4bda1bcc3e20b16e8e2709e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Toto je m\u00e1 druh\u00e1 zpr\u00e1va o Dockeru. V dob\u011b prvn\u00ed zpr\u00e1vy jsme pou\u017e\u00edvali Docker pouze v Developmentu na stroj\u00edch v\u00fdvoj\u00e1\u0159\u016f. Po\u010det zam\u011bstnanc\u016f, kte\u0159\u00ed Docker pou\u017e\u00edvali, byl asi 2-3 osoby. Postupn\u011b jsme nasb\u00edrali zku\u0161enosti a pokro\u010dili jsme d\u00e1l. Odkaz na na\u0161i <noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/gled\/docker-development-70411088\">prvn\u00ed zpr\u00e1vu<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Co bude v t\u00e9to zpr\u00e1v\u011b? Pod\u011bl\u00edme se o zku\u0161enosti o tom, jak\u00e9 probl\u00e9my jsme potkali, a jak jsme je vy\u0159e\u0161ili. Ne v\u0161ude to bylo jednoduch\u00e9, ale umo\u017enilo n\u00e1m to pokro\u010dit d\u00e1l.<\/p>\n<p><\/p>\n<p>N\u00e1\u0161 slogan: dokeryzujte v\u0161e, co se v\u00e1m dostane do rukou.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25ae4f97f1c502384abfe697bac502b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00e9 probl\u00e9my \u0159e\u0161\u00edme?<\/p>\n<p><\/p>\n<p>Kdy\u017e je ve firm\u011b n\u011bkolik t\u00fdm\u016f, st\u00e1v\u00e1 se program\u00e1tor sd\u00edlen\u00fdm zdrojem. Jsou f\u00e1ze, kdy je program\u00e1tor vytr\u017een z jednoho projektu a d\u00e1n n\u011bjakou dobu do jin\u00e9ho projektu.<\/p>\n<p><\/p>\n<p>Aby se program\u00e1tor rychle zorientoval, mus\u00ed si st\u00e1hnout zdrojov\u00fd k\u00f3d projektu a co nejrychleji spustit prost\u0159ed\u00ed, kter\u00e9 mu umo\u017en\u00ed pokra\u010dovat v \u0159e\u0161en\u00ed \u00fakol\u016f tohoto projektu.<\/p>\n<p><\/p>\n<p>Obvykle, pokud za\u010d\u00edn\u00e1me od nuly, je v projektu m\u00e1lo dokumentace. Informace o nastaven\u00ed znaj\u00ed jen sta\u0159\u00ed pracovn\u00edci. Zam\u011bstnanci si obvykle nastavuj\u00ed sv\u00e9 pracovn\u00ed m\u00edsto za jeden nebo dva dny. Abychom to urychlili, pou\u017eili jsme Docker.<\/p>\n<p><\/p>\n<p>Dal\u0161\u00edm d\u016fvodem je standardizace nastaven\u00ed v prost\u0159ed\u00ed Development. Z m\u00e9 zku\u0161enosti si v\u00fdvoj\u00e1\u0159i v\u017edy d\u00e1vaj\u00ed z\u00e1le\u017eet. V ka\u017ed\u00e9m p\u00e1t\u00e9m p\u0159\u00edpad\u011b se zav\u00e1d\u00ed vlastn\u00ed dom\u00e9na, nap\u0159\u00edklad vasya.dev. Vedle sed\u00ed soused Petya, kter\u00fd m\u00e1 dom\u00e9nu petya.dev. Vyv\u00edjej\u00ed web nebo n\u011bjakou komponentu syst\u00e9mu pomoc\u00ed t\u00e9to dom\u00e9ny.<\/p>\n<p><\/p>\n<p>Kdy\u017e se syst\u00e9m rozr\u016fst\u00e1 a tyto dom\u00e9ny se za\u010d\u00ednaj\u00ed objevovat v konfigurac\u00edch, vznik\u00e1 konflikt v\u00fdvojov\u00fdch prost\u0159ed\u00ed a p\u0159episuje se cesta na web.<\/p>\n<p><\/p>\n<p>Tot\u00e9\u017e se d\u011bje s nastaven\u00edm datab\u00e1z\u00ed. N\u011bkdo si ned\u00e1v\u00e1 pozor na bezpe\u010dnost a pracuje s pr\u00e1zdn\u00fdm heslem pro root. N\u011bkomu p\u0159i instalaci MySQL po\u017eadovalo heslo a to bylo 123. \u010casto se st\u00e1v\u00e1, \u017ee konfigurace datab\u00e1ze se neust\u00e1le m\u011bnila v z\u00e1vislosti na komitech v\u00fdvoj\u00e1\u0159e. N\u011bkdo to opravil, n\u011bkdo ne. Existovaly kli\u010dky, kdy jsme vyv\u00e1d\u011bli n\u011bjakou testovac\u00ed konfiguraci do <code>.gitignore<\/code> a ka\u017ed\u00fd v\u00fdvoj\u00e1\u0159 si musel nastavovat datab\u00e1zi. To zt\u011b\u017eovalo zah\u00e1jen\u00ed procesu. Je t\u0159eba krom\u011b v\u0161ech ostatn\u00edch v\u011bc\u00ed myslet na datab\u00e1zi. Datab\u00e1zi je nutn\u00e9 inicializovat, je t\u0159eba napsat heslo, vytvo\u0159it u\u017eivatele, vytvo\u0159it tabulku a tak d\u00e1le.<\/p>\n<p><\/p>\n<p>Dal\u0161\u00edm probl\u00e9mem jsou r\u016fzn\u00e9 verze knihoven. \u010casto se st\u00e1v\u00e1, \u017ee v\u00fdvoj\u00e1\u0159 pracuje na r\u016fzn\u00fdch projektech. Je tu Legacy projekt, kter\u00fd za\u010dali p\u0159ed p\u011bti lety (od roku 2017 \u2014 pozn. red.). Na za\u010d\u00e1tku startovali s MySQL 5.5. Existuj\u00ed i modern\u00ed projekty, kde se sna\u017e\u00edme zav\u00e1d\u011bt ji\u017e modern\u011bj\u0161\u00ed verze MySQL, nap\u0159\u00edklad 5.7 nebo nov\u011bj\u0161\u00ed (v roce 2017 \u2014 pozn. red.)<\/p>\n<p><\/p>\n<p>Ten, kdo pracuje s MySQL, v\u00ed, \u017ee tyto knihovny t\u00e1hnou za sebou z\u00e1vislosti. Je pom\u011brn\u011b problematick\u00e9 spustit 2 datab\u00e1ze sou\u010dasn\u011b. Minim\u00e1ln\u011b je problematick\u00e9 p\u0159ipojit star\u00e9 klienty k nov\u00e9 datab\u00e1zi. To zase vyvol\u00e1v\u00e1 n\u011bkolik probl\u00e9m\u016f.<\/p>\n<p><\/p>\n<p>Dal\u0161\u00ed probl\u00e9m nast\u00e1v\u00e1, kdy\u017e v\u00fdvoj\u00e1\u0159 pracuje na m\u00edstn\u00edm po\u010d\u00edta\u010di, pou\u017e\u00edv\u00e1 m\u00edstn\u00ed zdroje, m\u00edstn\u00ed soubory a m\u00edstn\u00ed RAM. Ve\u0161ker\u00e1 interakce b\u011bhem v\u00fdvoje \u0159e\u0161en\u00ed se odehr\u00e1v\u00e1 v r\u00e1mci toho, jak to funguje na jednom za\u0159\u00edzen\u00ed. Nap\u0159\u00edklad, kdy\u017e m\u00e1me v prost\u0159ed\u00ed produkce t\u0159i backendov\u00e9 servery a v\u00fdvoj\u00e1\u0159 ukl\u00e1d\u00e1 soubory do ko\u0159enov\u00e9ho adres\u00e1\u0159e, odkud nginx na\u010d\u00edt\u00e1 soubory pro odpov\u011b\u010f na dotazy. Kdy\u017e se takov\u00fd k\u00f3d dostane do produkce, vypl\u00fdv\u00e1 to, \u017ee soubor je p\u0159\u00edtomen na jednom ze t\u0159\u00ed server\u016f.<\/p>\n<p><\/p>\n<p>Nyn\u00ed se rozv\u00edj\u00ed oblast mikroslu\u017eeb. Kdy\u017e d\u011bl\u00edme na\u0161e velk\u00e9 aplikace na mal\u00e9 komponenty, kter\u00e9 mezi sebou komunikuj\u00ed. To n\u00e1m umo\u017e\u0148uje zvolit technologie specifick\u00e9 pro konkr\u00e9tn\u00ed \u00fakoly. Tak\u00e9 to umo\u017e\u0148uje rozd\u011blit pr\u00e1ci a z\u00f3nu odpov\u011bdnosti mezi v\u00fdvoj\u00e1\u0159i.<\/p>\n<p><\/p>\n<p>Frontendov\u00fd v\u00fdvoj\u00e1\u0159, pracuj\u00edc\u00ed na JS, prakticky neovliv\u0148uje backend. Backendov\u00fd v\u00fdvoj\u00e1\u0159 naopak vyv\u00edj\u00ed, v na\u0161em p\u0159\u00edpad\u011b, pomoc\u00ed Ruby on Rails, a nezasahuje do frontendu. Interakce prob\u00edh\u00e1 pomoc\u00ed API.<\/p>\n<p><\/p>\n<p>Jako bonus n\u00e1m pomoc\u00ed Dockeru poda\u0159ilo efektivn\u011b vyu\u017e\u00edt zdroje na Stagingu. Ka\u017ed\u00fd projekt vy\u017eadoval ur\u010dit\u00e9 nastaven\u00ed kv\u016fli jeho specifice. Fyzicky bylo nutn\u00e9 vy\u010dlenit bu\u010f virtu\u00e1ln\u00ed server a nastavit jej samostatn\u011b, nebo rozd\u011blit n\u011bjak\u00e9 prom\u011bnn\u00e9 prost\u0159ed\u00ed, aby projekty mohly vz\u00e1jemn\u011b ovliv\u0148ovat jedna druhou v z\u00e1vislosti na verz\u00edch knihoven.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/fa5c99f90faef84a356d4791fd915830.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>N\u00e1stroje. Co pou\u017e\u00edv\u00e1me? <\/p>\n<p><\/p>\n<ul>\n<li>P\u0159\u00edmo samotn\u00fd Docker. V Dockerfile jsou pops\u00e1ny z\u00e1vislosti jednoho aplikace. <\/li>\n<li>Docker-compose - to je spojen\u00ed, kter\u00e9 spojuje n\u011bkolik na\u0161ich Docker aplikac\u00ed.<\/li>\n<li>GitLab pou\u017e\u00edv\u00e1me pro ulo\u017een\u00ed zdrojov\u00e9ho k\u00f3du.<\/li>\n<li>GitLab-CI pou\u017e\u00edv\u00e1me pro syst\u00e9movou integraci.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/b6041827a6ba928e0d33add6b79c581c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prezentace se skl\u00e1d\u00e1 ze dvou \u010d\u00e1st\u00ed.<\/p>\n<p><\/p>\n<p>Prvn\u00ed \u010d\u00e1st se zam\u011b\u0159\u00ed na to, jak jsme spou\u0161t\u011bli Docker na po\u010d\u00edta\u010d\u00edch v\u00fdvoj\u00e1\u0159\u016f.<\/p>\n<p><\/p>\n<p>Druh\u00e1 \u010d\u00e1st se zam\u011b\u0159\u00ed na to, jak komunikovat s GitLabem, jak spou\u0161t\u00edme testy a jak nasazujeme na Staging.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/45746d3323d35e0d18f066c8bfcb2214.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker je technologie, kter\u00e1 umo\u017e\u0148uje (pou\u017eit\u00edm deklarativn\u00edho p\u0159\u00edstupu) popsat pot\u0159ebn\u00e9 komponenty. To je p\u0159\u00edklad Dockerfile. Zde deklarujeme, \u017ee d\u011bd\u00edme z ofici\u00e1ln\u00edho Docker obrazu Ruby:2.3.0. Obsahuje nainstalovan\u00fd Ruby verze 2.3. Instalujeme pot\u0159ebn\u00e9 knihovny pro sestaven\u00ed a NodeJS. Popisujeme, \u017ee vytv\u00e1\u0159\u00edme adres\u00e1\u0159. <code>\/app<\/code>Ur\u010dujeme adres\u00e1\u0159 app jako pracovn\u00ed adres\u00e1\u0159. Do tohoto adres\u00e1\u0159e um\u00edst\u00edme pot\u0159ebn\u00e9 minim\u00e1ln\u00ed soubory Gemfile a Gemfile.lock. Pot\u00e9 provedeme build projekt\u016f, kter\u00e9 instaluj\u00ed tento obraz z\u00e1vislost\u00ed. Uv\u00e1d\u00edme, \u017ee kontejner bude p\u0159ipraven naslouchat na extern\u00edm portu 3000. Posledn\u00ed p\u0159\u00edkaz je p\u0159\u00edkaz, kter\u00fd p\u0159\u00edmo spou\u0161t\u00ed na\u0161i aplikaci. Pokud spust\u00edme p\u0159\u00edkaz pro spu\u0161t\u011bn\u00ed projektu, aplikace se pokus\u00ed vykonat a spust\u00ed uveden\u00fd p\u0159\u00edkaz.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ba503c305ae90f49b39f4ae2cbda1668.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Toto je minim\u00e1ln\u00ed p\u0159\u00edklad souboru docker-compose. V tomto p\u0159\u00edpad\u011b ukazujeme, jak prob\u00edh\u00e1 propojen\u00ed dvou kontejner\u016f. To je p\u0159\u00edmo ve slu\u017eb\u011b datab\u00e1ze a slu\u017eb\u011b web. Na\u0161e webov\u00e9 aplikace v\u011bt\u0161inou vy\u017eaduj\u00ed jako backend n\u011bjakou datab\u00e1zi pro ukl\u00e1d\u00e1n\u00ed dat. Proto\u017ee pou\u017e\u00edv\u00e1me MySQL, m\u00e1me p\u0159\u00edklad s MySQL \u2014 ale nic nebr\u00e1n\u00ed pou\u017eit\u00ed jin\u00e9 datab\u00e1ze (PostgreSQL, Redis).<\/p>\n<p><\/p>\n<p>Bereme ofici\u00e1ln\u00ed obraz MySQL 5.7.14 z Docker hubu bez zm\u011bn. Obraz, kter\u00fd odpov\u00edd\u00e1 na\u0161\u00ed webov\u00e9 aplikaci, budujeme z aktu\u00e1ln\u00edho adres\u00e1\u0159e. P\u0159i prvn\u00edm spu\u0161t\u011bn\u00ed tedy vytvo\u0159\u00edme obraz. Pot\u00e9 spust\u00edme p\u0159\u00edkaz, kter\u00fd zde vykon\u00e1v\u00e1me. Pokud se vr\u00e1t\u00edme zp\u011bt, uvid\u00edme, \u017ee byla ur\u010dena p\u0159\u00edkaz pro spu\u0161t\u011bn\u00ed p\u0159es Puma. Puma je slu\u017eba napsan\u00e1 v Ruby. Ve druh\u00e9m p\u0159\u00edpad\u011b p\u0159episujeme. Tento p\u0159\u00edkaz m\u016f\u017ee b\u00fdt libovoln\u00fd podle na\u0161ich pot\u0159eb nebo \u00fakol\u016f.<\/p>\n<p><\/p>\n<p>Tak\u00e9 popisujeme, co je pot\u0159eba pro forward port na na\u0161\u00ed hostitelsk\u00e9 ma\u0161in\u011b v\u00fdvoj\u00e1\u0159e z portu 3000 na port 3000 kontejneru. To se prov\u00e1d\u00ed automaticky pomoc\u00ed iptables a vlastn\u00edho mechanismu, kter\u00fd je p\u0159\u00edmo zakotven v Dockeru. <\/p>\n<p><\/p>\n<p>V\u00fdvoj\u00e1\u0159 se tak\u00e9 m\u016f\u017ee, stejn\u011b jako d\u0159\u00edve, obr\u00e1tit na jakoukoli dostupnou IP adresu, nap\u0159\u00edklad 127.0.0.1 m\u00edstn\u00ed nebo extern\u00ed IP adresu stroje.<\/p>\n<p><\/p>\n<p>Posledn\u00ed \u0159\u00e1dek \u0159\u00edk\u00e1, \u017ee kontejner web z\u00e1vis\u00ed na kontejneru db. Kdy\u017e spust\u00edme kontejner web, docker-compose p\u0159edt\u00edm spust\u00ed na\u0161i datab\u00e1zi. Ji\u017e po startu datab\u00e1ze (ve skute\u010dnosti \u2014 po spu\u0161t\u011bn\u00ed kontejneru! To nezaru\u010duje p\u0159ipravenost DB) se spust\u00ed na\u0161e aplikace, n\u00e1\u0161 backend.<\/p>\n<p><\/p>\n<p>To umo\u017e\u0148uje vyvarovat se chyb, kdy\u017e datab\u00e1ze nen\u00ed spu\u0161t\u011bna, a \u0161et\u0159\u00ed zdroje, kdy\u017e zastav\u00edme kontejner datab\u00e1ze, uvol\u0148uj\u00edc\u00ed tak zdroje pro jin\u00e9 projekty. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4acbcf5de89b98db055e8abc419202de.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co n\u00e1m p\u0159in\u00e1\u0161\u00ed pou\u017eit\u00ed dockerizace datab\u00e1z\u00ed v projektu. U v\u0161ech v\u00fdvoj\u00e1\u0159\u016f evidujeme verzi MySQL. To n\u00e1m umo\u017e\u0148uje vyhnout se n\u011bkter\u00fdm chyb\u00e1m, kter\u00e9 mohou nastat p\u0159i nesouladu verz\u00ed, kdy\u017e se m\u011bn\u00ed syntaxe, konfigurace a v\u00fdchoz\u00ed nastaven\u00ed. To n\u00e1m umo\u017e\u0148uje specifikovat spole\u010dn\u00e9 hostname pro datab\u00e1zi, login a heslo. Odlou\u010d\u00edme se od toho chaosu n\u00e1zv\u016f a konflikt\u016f v konfigura\u010dn\u00edch souborech, kter\u00e9 byly d\u0159\u00edve. <\/p>\n<p><\/p>\n<p>M\u00e1me mo\u017enost pou\u017e\u00edt optimalizovanou konfiguraci pro v\u00fdvojov\u00e9 prost\u0159ed\u00ed, kter\u00e1 se bude li\u0161it od v\u00fdchoz\u00ed. MySQL je ve v\u00fdchoz\u00edm nastaven\u00ed nastaveno na slab\u0161\u00ed stroje a jeho v\u00fdkon je z boxu velmi n\u00edzk\u00fd.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/417d77a06b18e2df9b71440c0f2a1653.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Docker n\u00e1m umo\u017e\u0148uje pou\u017e\u00edvat interpretery Python, Ruby, NodeJS, PHP ve pot\u0159ebn\u00fdch verz\u00edch. Zbavujeme se tak pot\u0159eby pou\u017e\u00edvat n\u011bjak\u00e9ho spr\u00e1vce verz\u00ed. D\u0159\u00edve jsme pro Ruby pou\u017e\u00edvali rpm bal\u00ed\u010dek, kter\u00fd umo\u017e\u0148oval m\u011bnit verzi v z\u00e1vislosti na projektu. D\u00edky Docker kontejneru tak\u00e9 hladce migrujeme k\u00f3d a verzionujeme ho spolu se z\u00e1vislostmi. Nem\u00e1me probl\u00e9m rozli\u0161it verzi jak interpreta, tak k\u00f3du. Pro aktualizaci verze je t\u0159eba zastavit star\u00fd kontejner a spustit nov\u00fd. Pokud n\u011bco nevyjde, m\u016f\u017eeme zastavit nov\u00fd kontejner a spustit star\u00fd.<\/p>\n<p><\/p>\n<p>Po sestaven\u00ed obrazu budou kontejnery jak v developmentu, tak v produkci toto\u017en\u00e9. To je obzvl\u00e1\u0161\u0165 d\u016fle\u017eit\u00e9 pro velk\u00e9 instalace.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/185a1bfe257f7e3e0eecdc6e0e0d330f.jpg\" style=\"display:block;margin: 0 auto;\" \/> Na frontendu pou\u017e\u00edv\u00e1me JavaScript a NodeJS.<\/p>\n<p><\/p>\n<p>N\u00e1\u0161 posledn\u00ed projekt b\u011b\u017e\u00ed na ReactJS. V\u00fdvoj\u00e1\u0159 spou\u0161t\u011bl v\u0161echny kontejnery a vyv\u00edjel pomoc\u00ed hot-reload.<\/p>\n<p><\/p>\n<p>D\u00e1le se spou\u0161t\u00ed \u00faloha na sestaven\u00ed JavaScriptu a k\u00f3d, kter\u00fd byl sestaven do statiky, se poskytuje p\u0159es nginx, \u010d\u00edm\u017e se \u0161et\u0159\u00ed zdroje.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4c2e28319d56d7fc81845b4133a1bfe6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zde jsem p\u0159edlo\u017eil sch\u00e9ma na\u0161eho posledn\u00edho projektu.<\/p>\n<p><\/p>\n<p>Jak\u00e9 \u00fakoly jsme \u0159e\u0161ili? Nastala pot\u0159eba vybudovat syst\u00e9m, kter\u00fd komunikuje s mobiln\u00edmi za\u0159\u00edzen\u00edmi. Ta z\u00edsk\u00e1vaj\u00ed data. Jednou z mo\u017enost\u00ed je pos\u00edlat push notifikace do t\u011bchto za\u0159\u00edzen\u00ed. <\/p>\n<p><\/p>\n<p>Co jsme pro to ud\u011blali?<\/p>\n<p><\/p>\n<p>Rozd\u011blili jsme aplikaci na komponenty jako: administra\u010dn\u00ed \u010d\u00e1st v JS, backend, kter\u00fd funguje p\u0159es REST rozhran\u00ed pod Ruby on Rails. Backend komunikuje s datab\u00e1z\u00ed. V\u00fdsledky, kter\u00e9 se generuj\u00ed, se p\u0159ed\u00e1vaj\u00ed klientovi. Administra\u010dn\u00ed rozhran\u00ed komunikuje s backendem a datab\u00e1z\u00ed p\u0159es REST rozhran\u00ed.<\/p>\n<p><\/p>\n<p>Tak\u00e9 jsme pot\u0159ebovali odes\u00edlat push ozn\u00e1men\u00ed. P\u0159edt\u00edm jsme m\u011bli projekt, ve kter\u00e9m byl realizov\u00e1n mechanismus, kter\u00fd odpov\u00edd\u00e1 za doru\u010dov\u00e1n\u00ed ozn\u00e1men\u00ed na mobiln\u00ed platformy. <\/p>\n<p><\/p>\n<p>Vyvinuli jsme takovou sch\u00e9ma: oper\u00e1tor z prohl\u00ed\u017ee\u010de interaguje s administra\u010dn\u00edm rozhran\u00edm, administra\u010dn\u00ed rozhran\u00ed interaguje s backendem, a je polo\u017eena \u00faloha, \u017ee je pot\u0159eba poslat push ozn\u00e1men\u00ed.<\/p>\n<p><\/p>\n<p>Push ozn\u00e1men\u00ed interaguj\u00ed s jinou komponentou, kter\u00e1 je realizov\u00e1na na NodeJS.<\/p>\n<p><\/p>\n<p>Buduj\u00ed se fronty a d\u00e1le prob\u00edh\u00e1 odes\u00edl\u00e1n\u00ed ozn\u00e1men\u00ed podle sv\u00e9ho mechanismu.<\/p>\n<p><\/p>\n<p>Zde jsou zn\u00e1zorn\u011bny dv\u011b datab\u00e1ze. V sou\u010dasn\u00e9 dob\u011b pou\u017e\u00edv\u00e1me pomoc\u00ed Dockeru 2 nez\u00e1visl\u00e9 datab\u00e1ze, kter\u00e9 nejsou nijak propojen\u00e9. Krom\u011b toho maj\u00ed spole\u010dnou virtu\u00e1ln\u00ed s\u00ed\u0165, a fyzick\u00e1 data se ukl\u00e1daj\u00ed v r\u016fzn\u00fdch adres\u00e1\u0159\u00edch na stroji v\u00fdvoj\u00e1\u0159e.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/dfde59db7e6886d2d851dcf884049318.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tot\u00e9\u017e, ale v \u010d\u00edslech. Zde je d\u016fle\u017eit\u00e9 op\u011btovn\u00e9 pou\u017eit\u00ed k\u00f3du.<\/p>\n<p><\/p>\n<p>Pokud jsme d\u0159\u00edve mluvili o op\u011btovn\u00e9m pou\u017eit\u00ed k\u00f3du ve form\u011b knihoven, v tomto p\u0159\u00edkladu se n\u00e1\u0161 servis, kter\u00fd odpov\u00edd\u00e1 za push ozn\u00e1men\u00ed, op\u011btovn\u011b pou\u017e\u00edv\u00e1 jako kompletn\u00ed server. Poskytuje API. A s n\u00edm ji\u017e interaguje na\u0161e nov\u00e1 v\u00fdvoj.<\/p>\n<p><\/p>\n<p>V t\u00e9 dob\u011b jsme pou\u017e\u00edvali 4 verzi NodeJS. Nyn\u00ed (v roce 2017 \u2014 pozn. red.) p\u0159i nov\u00fdch projektech pou\u017e\u00edv\u00e1me 7 verzi NodeJS. Nen\u00ed probl\u00e9m v nov\u00fdch komponent\u00e1ch pou\u017e\u00edvat nov\u00e9 verze knihoven. <\/p>\n<p><\/p>\n<p>V p\u0159\u00edpad\u011b pot\u0159eby je mo\u017en\u00e9 prov\u00e9st refaktoring a zv\u00fd\u0161it verzi NodeJS u slu\u017eby push ozn\u00e1men\u00ed. <\/p>\n<p><\/p>\n<p>A pokud se n\u00e1m poda\u0159\u00ed zachovat kompatibilitu podle API, bude mo\u017en\u00e9 ji nahradit v jin\u00fdch projektech, kter\u00e9 byly d\u0159\u00edve pou\u017eity.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5c58c65be078a5a1b9fc17ee2e7b4ad4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co je pot\u0159eba k p\u0159id\u00e1n\u00ed Dockeru? P\u0159id\u00e1v\u00e1me do na\u0161eho repozit\u00e1\u0159e Dockerfile, kter\u00fd popisuje nezbytn\u00e9 z\u00e1vislosti. V tomto p\u0159\u00edkladu jsou komponenty rozd\u011bleny podle logiky. To je minim\u00e1ln\u00ed soubor pro backendov\u00e9ho v\u00fdvoj\u00e1\u0159e.<\/p>\n<p><\/p>\n<p>P\u0159i vytv\u00e1\u0159en\u00ed nov\u00e9ho projektu vytvo\u0159\u00edme Dockerfile, pop\u00ed\u0161eme pot\u0159ebnou ekosyst\u00e9m (Python, Ruby, NodeJS). V docker-compose popisujeme nezbytnou z\u00e1vislost \u2014 datab\u00e1zi. Uv\u00e1d\u00edme, \u017ee pot\u0159ebujeme datab\u00e1zi takov\u00e9 verze, ukl\u00e1dat data tam a tam.<\/p>\n<p><\/p>\n<p>Pou\u017e\u00edv\u00e1me k poskytov\u00e1n\u00ed statiky samostatn\u00fd t\u0159et\u00ed kontejner s nginx. Je zaji\u0161t\u011bna mo\u017enost nahr\u00e1v\u00e1n\u00ed obr\u00e1zk\u016f. Backend je ukl\u00e1d\u00e1 do p\u0159edem p\u0159ipraven\u00e9ho svazku, kter\u00fd je tak\u00e9 namontov\u00e1n v kontejneru s nginx, kter\u00fd poskytuje statiku.<\/p>\n<p><\/p>\n<p>Aby uchovat konfiguraci nginx a mysql, vytvo\u0159ili jsme slo\u017eku Docker, ve kter\u00e9 uchov\u00e1v\u00e1me pot\u0159ebn\u00e9 konfigura\u010dn\u00ed soubory. Kdy\u017e si v\u00fdvoj\u00e1\u0159 provede git clone repozit\u00e1\u0159e na sv\u016fj stroj, z\u00edsk\u00e1 ji\u017e projekt p\u0159ipraven\u00fd pro lok\u00e1ln\u00ed v\u00fdvoj. Nevyvst\u00e1v\u00e1 ot\u00e1zka, kter\u00fd port nebo jak\u00e1 nastaven\u00ed aplikovat.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/e7a6b308a75cacf8ce60687a9e6081dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>D\u00e1le m\u00e1me n\u011bkolik komponent: administr\u00e1tor, informa\u010dn\u00ed API, push notifikace.<\/p>\n<p><\/p>\n<p>Abychom to v\u0161echno spustili, vytvo\u0159ili jsme dal\u0161\u00ed repozit\u00e1\u0159, kter\u00fd jsme nazvali dockerized-app. V sou\u010dasn\u00e9 dob\u011b pou\u017e\u00edv\u00e1me n\u011bkolik repozit\u00e1\u0159\u016f pro ka\u017edou komponentu. Ty se logicky li\u0161\u00ed \u2014 v GitLabu to vypad\u00e1 jako slo\u017eka, a na stroji v\u00fdvoj\u00e1\u0159e jako slo\u017eka pro konkr\u00e9tn\u00ed projekt. Na ni\u017e\u0161\u00ed \u00farovni se nach\u00e1zej\u00ed komponenty, kter\u00e9 se budou spojovat.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f4e2c45c8ec20fca0bac74b3a3892543.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>To je p\u0159\u00edklad obsahu dockerized-app. Tak\u00e9 jsme sem um\u00edstili adres\u00e1\u0159 Docker, ve kter\u00e9m pln\u00edme konfigurace pot\u0159ebn\u00e9 pro interakce v\u0161ech komponent. Je zde README.md, ve kter\u00e9m je kr\u00e1tce pops\u00e1no, jak spustit projekt.<\/p>\n<p><\/p>\n<p>Zde jsme pou\u017eili dva soubory docker-compose. To bylo ud\u011bl\u00e1no, aby bylo mo\u017en\u00e9 spou\u0161t\u011bt je postupn\u011b. Kdy\u017e v\u00fdvoj\u00e1\u0159 pracuje s j\u00e1drem a nepot\u0159ebuje push notifikace, jednodu\u0161e spust\u00ed pouze soubor docker-compose, \u010d\u00edm\u017e se \u0161et\u0159\u00ed syst\u00e9mov\u00e9 zdroje.<\/p>\n<p><\/p>\n<p>Pokud je pot\u0159eba integrovat push notifikace, spust\u00ed se docker-compose.yaml a docker-compose-push.yaml.<\/p>\n<p><\/p>\n<p>Proto\u017ee docker-compose.yaml a docker-compose-push.yaml jsou um\u00edst\u011bny ve slo\u017ece, automaticky se vytvo\u0159\u00ed jednotn\u00e1 virtu\u00e1ln\u00ed s\u00ed\u0165.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/535019c82c72c1602176fbaf4aa5640f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Popis komponent. To je podrobn\u011bj\u0161\u00ed soubor, kter\u00fd odpov\u00edd\u00e1 za shrom\u00e1\u017ed\u011bn\u00ed komponent. Co je tu pozoruhodn\u00e9? Zde zav\u00e1d\u00edme komponent vyv\u00e1\u017ee\u010d.<\/p>\n<p><\/p>\n<p>To je hotov\u00fd Docker obraz, ve kter\u00e9m se spou\u0161t\u00ed nginx a aplikace, kter\u00e1 naslouch\u00e1 Docker socketu. Dynamicky, p\u0159i zap\u00edn\u00e1n\u00ed a vyp\u00edn\u00e1n\u00ed kontejner\u016f, regeneruje konfiguraci nginx. Komunikaci s komponentami rozd\u011bl\u00edme podle dom\u00e9nov\u00fdch jmen t\u0159et\u00ed \u00farovn\u011b.<\/p>\n<p><\/p>\n<p>Pro prost\u0159ed\u00ed v\u00fdvoje pou\u017e\u00edv\u00e1me dom\u00e9nu .dev \u2014 api.informer.dev. Aplikace s dom\u00e9nou .dev je dostupn\u00e1 na lok\u00e1ln\u00edm stroji v\u00fdvoj\u00e1\u0159e.<\/p>\n<p><\/p>\n<p>Pak se p\u0159en\u00e1\u0161ej\u00ed konfigurace do ka\u017ed\u00e9ho projektu a v\u0161echny projekty se spou\u0161t\u00ed spole\u010dn\u011b najednou.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/bc1e11e6f1fd1c837d2c8087d04145c4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pokud bychom to graficky zn\u00e1zornili, dostal by se klient jako n\u00e1\u0161 prohl\u00ed\u017ee\u010d nebo jin\u00fd n\u00e1stroj, kter\u00fdm prov\u00e1d\u00edme dotazy na vyv\u00e1\u017ee\u010d.<\/p>\n<p><\/p>\n<p>Vyv\u00e1\u017ee\u010d na z\u00e1klad\u011b dom\u00e9nov\u00e9ho jm\u00e9na ur\u010duje, ke kter\u00e9mu kontejneru se m\u00e1 obr\u00e1tit.<\/p>\n<p><\/p>\n<p>M\u016f\u017ee to b\u00fdt nginx, kter\u00fd poskytuje JS admin panelu. M\u016f\u017ee to b\u00fdt nginx, kter\u00fd dod\u00e1v\u00e1 API nebo statick\u00e9 soubory, kter\u00e9 nginx zas\u00edl\u00e1 jako na\u010d\u00edt\u00e1n\u00ed obr\u00e1zk\u016f.<\/p>\n<p><\/p>\n<p>Na sch\u00e9matu je vid\u011bt, \u017ee kontejnery jsou propojeny virtu\u00e1ln\u00ed s\u00edt\u00ed a skryty za proxy.<\/p>\n<p><\/p>\n<p>Na v\u00fdvoj\u00e1\u0159sk\u00e9m stroji je mo\u017en\u00e9 p\u0159istoupit ke kontejneru, pokud zn\u00e1te IP, ale v z\u00e1sad\u011b to nepou\u017e\u00edv\u00e1me. Pot\u0159eba p\u0159\u00edm\u00e9ho p\u0159\u00edstupu prakticky nenast\u00e1v\u00e1.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/2908c31fd9d3c79f6189bdbeeb6d028f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00fd p\u0159\u00edklad bych m\u011bl sledovat, abych dockerizoval svou aplikaci? Podle m\u00e9ho n\u00e1zoru je dobr\u00fdm p\u0159\u00edkladem ofici\u00e1ln\u00ed docker obraz pro MySQL.<\/p>\n<p><\/p>\n<p>Je to dost slo\u017eit\u00e9. Existuje mnoho verz\u00ed. Ale jeho funk\u010dnost pokr\u00fdv\u00e1 mno\u017estv\u00ed pot\u0159eb, kter\u00e9 mohou vzniknout b\u011bhem dal\u0161\u00edho v\u00fdvoje. Pokud str\u00e1v\u00edte \u010das a pochop\u00edte, jak v\u0161e spolu souvis\u00ed, mysl\u00edm, \u017ee v samostatn\u00e9m nasazen\u00ed nebudete m\u00edt \u017e\u00e1dn\u00e9 probl\u00e9my.<\/p>\n<p><\/p>\n<p>Na hub.docker.com obvykle naleznete odkazy na github.com, kde jsou uvedena p\u0159\u00edmo syrov\u00e1 data, z nich\u017e si m\u016f\u017eete sami sestavit obraz.<\/p>\n<p><\/p>\n<p>D\u00e1le v tomto repozit\u00e1\u0159i je skript docker-endpoint.sh, kter\u00fd zaji\u0161\u0165uje prim\u00e1rn\u00ed inicializaci a dal\u0161\u00ed zpracov\u00e1n\u00ed spu\u0161t\u011bn\u00ed aplikace.<\/p>\n<p><\/p>\n<p>Tento p\u0159\u00edklad tak\u00e9 nab\u00edz\u00ed mo\u017enost konfigurace pomoc\u00ed prom\u011bnn\u00fdch prost\u0159ed\u00ed. Ur\u010den\u00edm prom\u011bnn\u00e9 prost\u0159ed\u00ed p\u0159i spu\u0161t\u011bn\u00ed jednotliv\u00e9ho kontejneru nebo prost\u0159ednictv\u00edm docker-compose m\u016f\u017eete \u0159\u00edci, \u017ee pot\u0159ebujeme nastavit pr\u00e1zdn\u00e9 heslo pro docker pro u\u017eivatele root na MySQL nebo n\u011bjak\u00e9, kter\u00e9 chceme.<\/p>\n<p><\/p>\n<p>Existuje mo\u017enost vytvo\u0159it n\u00e1hodn\u00e9 heslo. \u0158\u00edk\u00e1me, \u017ee pot\u0159ebujeme u\u017eivatele, je nutn\u00e9 nastavit heslo pro u\u017eivatele a vytvo\u0159it datab\u00e1zi.<\/p>\n<p><\/p>\n<p>Ve sv\u00fdch projektech jsme pon\u011bkud unifikovali Dockerfile, kter\u00fd zaji\u0161\u0165uje inicializaci. Oprava byla provedena pro na\u0161e pot\u0159eby, aby bylo mo\u017en\u00e9 jednodu\u0161e roz\u0161\u00ed\u0159it pr\u00e1va u\u017eivatele, kter\u00e9 aplikace pou\u017e\u00edv\u00e1. To umo\u017enilo pozd\u011bji jednodu\u0161e vytvo\u0159it datab\u00e1zi z konzole aplikace. V Ruby aplikac\u00edch existuj\u00ed p\u0159\u00edkazy pro vytv\u00e1\u0159en\u00ed, zm\u011bnu a maz\u00e1n\u00ed datab\u00e1z\u00ed.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4a9b56e21819d28dd39753134d23fee4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tento p\u0159\u00edklad ukazuje, jak vypad\u00e1 konkr\u00e9tn\u00ed verze MySQL na github.com. Dockerfile lze otev\u0159\u00edt a pod\u00edvat se, jak tam prob\u00edh\u00e1 instalace.<\/p>\n<p><\/p>\n<p>docker-endpoint.sh je skript, kter\u00fd slou\u017e\u00ed jako vstupn\u00ed bod. P\u0159i prvotn\u00ed inicializaci je pot\u0159eba prov\u00e9st ur\u010dit\u00e9 akce na p\u0159\u00edpravu, a v\u0161echny tyto akce jsou vy\u010dlen\u011bny pr\u00e1v\u011b do init skriptu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/4153fa46526f3d802931dd1db48b08cd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u0159ejdeme k druh\u00e9 \u010d\u00e1sti.<\/p>\n<p><\/p>\n<p>Pro ulo\u017een\u00ed zdrojov\u00fdch k\u00f3d\u016f jsme p\u0159e\u0161li na gitlab. Je to dostate\u010dn\u011b v\u00fdkonn\u00fd syst\u00e9m, kter\u00fd m\u00e1 vizu\u00e1ln\u00ed rozhran\u00ed.<\/p>\n<p><\/p>\n<p>Jednou z komponent Gitlabu je Gitlab CI. Umo\u017e\u0148uje popsat posloupnost p\u0159\u00edkaz\u016f, kter\u00e9 budou n\u00e1sledn\u011b pou\u017eity pro organizaci syst\u00e9mu distribuce k\u00f3du nebo spu\u0161t\u011bn\u00ed automatick\u00fdch test\u016f.<\/p>\n<p><\/p>\n<p>Prezentace o Gitlab CI 2 <noindex><a rel=\"nofollow\" href=\"https:\/\/goo.gl\/uohKjI\">https:\/\/goo.gl\/uohKjI<\/a><\/noindex> \u2014 prezentace z Ruby Russia klubu \u2014 dostate\u010dn\u011b podrobn\u00e1 a mo\u017en\u00e1 v\u00e1s zaujme.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/5d26d20500f34eeb9768e6c3d91bbefa.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nyn\u00ed se pod\u00edv\u00e1me, co je pot\u0159eba pro aktivaci Gitlab CI. K jeho spu\u0161t\u011bn\u00ed sta\u010d\u00ed um\u00edstit soubor .gitlab-ci.yml do ko\u0159ene projektu.<\/p>\n<p><\/p>\n<p>Zde popisujeme, co chceme prov\u00e1d\u011bt, posloupnost stav\u016f typu testu a nasazen\u00ed.<\/p>\n<p><\/p>\n<p>Prov\u00e1d\u00edme skripty, kter\u00e9 p\u0159\u00edmo volaj\u00ed docker-compose pro sestaven\u00ed na\u0161\u00ed aplikace. To je p\u0159\u00edklad backendu.<\/p>\n<p><\/p>\n<p>D\u00e1le \u0159\u00edk\u00e1me, \u017ee je t\u0159eba spustit migrace pro zm\u011bny datab\u00e1ze a prov\u00e9st testy.<\/p>\n<p><\/p>\n<p>Pokud skripty prob\u00edhaj\u00ed spr\u00e1vn\u011b a nevrac\u00ed k\u00f3d chyby, syst\u00e9m p\u0159ech\u00e1z\u00ed do druh\u00e9 f\u00e1ze nasazen\u00ed.<\/p>\n<p><\/p>\n<p>F\u00e1ze nasazen\u00ed je v aktu\u00e1ln\u00edm okam\u017eiku realizov\u00e1na pro staging. Nenosili jsme bezprobl\u00e9mov\u00fd restart.<\/p>\n<p><\/p>\n<p>N\u00e1siln\u011b ukon\u010dujeme v\u0161echny kontejnerov\u00e9 slu\u017eby a pot\u00e9 je v\u0161echny znovu spou\u0161t\u00edme, sestaven\u00e9 v prvn\u00edm kroku p\u0159i testov\u00e1n\u00ed.<\/p>\n<p><\/p>\n<p>Zpracov\u00e1v\u00e1me migrace datab\u00e1ze pro aktu\u00e1ln\u00ed prom\u011bnn\u00e9 prost\u0159ed\u00ed, kter\u00e9 napsali v\u00fdvoj\u00e1\u0159i.<\/p>\n<p><\/p>\n<p>Je pozn\u00e1mka, \u017ee to pou\u017e\u00edt pouze pro v\u011btev master.<\/p>\n<p><\/p>\n<p>P\u0159i zm\u011bn\u011b jin\u00fdch v\u011btv\u00ed se nevykon\u00e1v\u00e1.<\/p>\n<p><\/p>\n<p>Existuje mo\u017enost organizovat nasazen\u00ed podle v\u011btv\u00ed.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/8a5b880bd9a0d4bab0b276568e2ba413.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pro dal\u0161\u00ed organizaci je pot\u0159eba nainstalovat Gitlab Runner.<\/p>\n<p><\/p>\n<p>Tato utilita je naps\u00e1na v Golangu. Je to jedin\u00fd soubor, jak je b\u011b\u017en\u00e9 ve sv\u011bt\u011b Golangu, kter\u00fd nevy\u017eaduje \u017e\u00e1dn\u00e9 z\u00e1vislosti.<\/p>\n<p><\/p>\n<p>P\u0159i spu\u0161t\u011bn\u00ed registrujeme Gitlab Runner.<\/p>\n<p><\/p>\n<p>Z\u00edsk\u00e1v\u00e1me v webov\u00e9m rozhran\u00ed Gitlab kl\u00ed\u010d.<\/p>\n<p><\/p>\n<p>Pot\u00e9 spou\u0161t\u00edme p\u0159\u00edkaz pro inicializaci v p\u0159\u00edkazov\u00e9m \u0159\u00e1dku.<\/p>\n<p><\/p>\n<p>Nastavujeme Gitlab Runner v dialogov\u00e9m re\u017eimu (Shell, Docker, VirtualBox, SSH).<\/p>\n<p><\/p>\n<p>K\u00f3d na Gitlab Runner bude spou\u0161t\u011bn p\u0159i ka\u017ed\u00e9m commitu v z\u00e1vislosti na nastaven\u00ed .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/37c8ac7499f0cfba2eb07a84083e44e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak to vizu\u00e1ln\u011b vypad\u00e1 v Gitlabu ve webov\u00e9m rozhran\u00ed. Po p\u0159ipojen\u00ed Gitlab CI se n\u00e1m objev\u00ed vlajka, kter\u00e1 ukazuje, v jak\u00e9m stavu se aktu\u00e1ln\u011b nach\u00e1z\u00ed build.<\/p>\n<p><\/p>\n<p>Vid\u00edme, \u017ee p\u0159ed 4 minutami byl proveden commit, kter\u00fd pro\u0161el v\u0161emi testy a nezp\u016fsobil \u017e\u00e1dn\u00e9 probl\u00e9my.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/33ac79c45f0651a5f8bde75092c4ac44.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>M\u016f\u017eeme se pod\u00edvat podrobn\u011bji na buildu. Zde vid\u00edme, \u017ee u\u017e prob\u011bhly dva stavy. Stav testov\u00e1n\u00ed a stav nasazen\u00ed na staging.<\/p>\n<p><\/p>\n<p>Pokud klikneme na konkr\u00e9tn\u00ed build, uvid\u00edme konzolov\u00fd v\u00fdstup p\u0159\u00edkaz\u016f, kter\u00e9 byly spu\u0161t\u011bny b\u011bhem procesu podle .gitlab-ci.yml.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d26dd28708c7fc8a409af4be4d48f502.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Takto vypad\u00e1 historie na\u0161eho produktu. Vid\u00edme, \u017ee byly \u00fasp\u011b\u0161n\u00e9 pokusy. Kdy\u017e testy sel\u017eou, tak se na dal\u0161\u00ed krok nep\u0159ejde a k\u00f3d na staging se neaktualizuje.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/ee7bd81dc283c7af0c194779d4230780.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00e9 \u00fakoly jsme \u0159e\u0161ili na staging, kdy\u017e jsme implementovali docker? N\u00e1\u0161 syst\u00e9m se skl\u00e1d\u00e1 z komponent a my jsme pot\u0159ebovali restartovat pouze ty komponenty, kter\u00e9 byly aktualizov\u00e1ny v repozit\u00e1\u0159i, a ne cel\u00fd syst\u00e9m jako celek.<\/p>\n<p><\/p>\n<p>Proto jsme museli v\u0161e rozd\u011blit do jednotliv\u00fdch slo\u017eek.<\/p>\n<p><\/p>\n<p>Po dokon\u010den\u00ed t\u00e9to zm\u011bny jsme \u010delili probl\u00e9mu, \u017ee Docker-compose vytv\u00e1\u0159\u00ed pro ka\u017edou slo\u017eku vlastn\u00ed prostor s\u00edt\u011b, co\u017e zabra\u0148uje komponent\u00e1m vid\u011bt sousedy.<\/p>\n<p><\/p>\n<p>Abychom to obe\u0161li, vytvo\u0159ili jsme s\u00ed\u0165 v Dockeru ru\u010dn\u011b. V Docker-compose jsme uvedli, aby pro tento projekt pou\u017e\u00edval tuto s\u00ed\u0165.<\/p>\n<p><\/p>\n<p>Takto ka\u017ed\u00fd komponent, kter\u00fd se spou\u0161t\u00ed s touto s\u00edt\u00ed, vid\u00ed komponenty v jin\u00fdch \u010d\u00e1stech syst\u00e9mu.<\/p>\n<p><\/p>\n<p>Dal\u0161\u00ed probl\u00e9m \u2013 to je d\u011blen\u00ed staging mezi n\u011bkolika projekty.<\/p>\n<p><\/p>\n<p>Aby to v\u0161echno vypadalo hezky a co nejbl\u00ed\u017ee produkci, je dobr\u00e9 pou\u017e\u00edvat port 80 nebo 443, kter\u00e9 se b\u011b\u017en\u011b pou\u017e\u00edvaj\u00ed ve webu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/f863cf1833271bf132455a70ad7d2706.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak jsme to vy\u0159e\u0161ili? P\u0159i\u0159adili jsme jednoho Gitlab Runnera v\u0161em velk\u00fdm projekt\u016fm.<\/p>\n<p><\/p>\n<p>Gitlab umo\u017e\u0148uje spustit n\u011bkolik distribuovan\u00fdch Gitlab Runner\u016f, kter\u00e9 budou jednodu\u0161e po \u0159ad\u011b v n\u00e1hodn\u00e9m po\u0159ad\u00ed br\u00e1t v\u0161echna zad\u00e1n\u00ed a prov\u00e1d\u011bt je.<\/p>\n<p><\/p>\n<p>Abychom p\u0159ede\u0161li chaosu, omezili jsme skupinu na\u0161ich projekt\u016f na jednoho Gitlab Runnera, kter\u00fd se p\u0159i na\u0161ich objemech bez probl\u00e9m\u016f vypo\u0159\u00e1d\u00e1v\u00e1.<\/p>\n<p><\/p>\n<p>Vy\u010dlenili jsme nginx-proxy do zvl\u00e1\u0161tn\u00edho spou\u0161t\u011bc\u00edho skriptu a do n\u011bj jsme zapsali s\u00edt\u011b v\u0161ech projekt\u016f. <\/p>\n<p><\/p>\n<p>N\u00e1\u0161 projekt m\u00e1 jednu s\u00ed\u0165, zat\u00edmco vyrovn\u00e1vac\u00ed server m\u00e1 n\u011bkolik s\u00edt\u00ed podle n\u00e1zv\u016f projekt\u016f. M\u016f\u017ee na z\u00e1klad\u011b dom\u00e9nov\u00fdch jmen d\u00e1le proxy.<\/p>\n<p><\/p>\n<p>P\u0159\u00edchoz\u00ed po\u017eadavky jsou sm\u011brov\u00e1ny na dom\u00e9nu p\u0159es port 80 a jsou spravov\u00e1ny skupinou kontejner\u016f, kter\u00e1 tuto dom\u00e9nu obsluhuje.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/25c769f029b272a17fd06bbe60cf0ea0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00e9 dal\u0161\u00ed probl\u00e9my se objevily? To, \u017ee ve v\u00fdchoz\u00edm nastaven\u00ed v\u0161echny kontejnery b\u011b\u017e\u00ed pod u\u017eivatelsk\u00fdm \u00fa\u010dtem root. Tento root nen\u00ed stejn\u00fd jako root hostitelsk\u00e9ho syst\u00e9mu.<\/p>\n<p><\/p>\n<p>Pokud se v\u0161ak p\u0159ihl\u00e1s\u00edte do kontejneru, budete m\u00edt root a soubor, kter\u00fd vytvo\u0159\u00edme v tomto kontejneru, z\u00edsk\u00e1 pr\u00e1va root.<\/p>\n<p><\/p>\n<p>Pokud se v\u00fdvoj\u00e1\u0159 p\u0159ihl\u00e1sil do kontejneru a vykonal n\u011bjak\u00e9 p\u0159\u00edkazy, kter\u00e9 generuj\u00ed soubory, a pot\u00e9 se odhl\u00e1sil z kontejneru, ve sv\u00e9 pracovn\u00ed slo\u017ece m\u00e1 soubor, ke kter\u00e9mu nem\u00e1 p\u0159\u00edstup.<\/p>\n<p><\/p>\n<p>Jak to lze vy\u0159e\u0161it? M\u016f\u017eeme p\u0159idat u\u017eivatele, kte\u0159\u00ed budou v kontejneru.<\/p>\n<p><\/p>\n<p>Jak\u00e9 probl\u00e9my nastaly, kdy\u017e jsme p\u0159idali u\u017eivatele?<\/p>\n<p><\/p>\n<p>P\u0159i vytv\u00e1\u0159en\u00ed u\u017eivatele se \u010dasto neshoduj\u00ed ID skupiny (UID) a ID u\u017eivatele (GID).<\/p>\n<p><\/p>\n<p>Abychom tento probl\u00e9m vy\u0159e\u0161ili, pou\u017e\u00edv\u00e1me v kontejneru u\u017eivatele s ID 1000.<\/p>\n<p><\/p>\n<p>V na\u0161em p\u0159\u00edpad\u011b to odpov\u00eddalo skute\u010dnosti, \u017ee prakticky v\u0161ichni v\u00fdvoj\u00e1\u0159i pou\u017e\u00edvaj\u00ed syst\u00e9m Ubuntu. A v syst\u00e9mu Ubuntu m\u00e1 prvn\u00ed u\u017eivatel ID 1000.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/d4911374e4953fdcd807c387efeafec3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00e9 m\u00e1me pl\u00e1ny?<\/p>\n<p><\/p>\n<p>P\u0159e\u010d\u00edst si dokumentaci k Dockeru. Projekt se aktivn\u011b vyv\u00edj\u00ed, dokumentace se m\u011bn\u00ed. \u00dadaje, kter\u00e9 byly z\u00edsk\u00e1ny p\u0159ed dv\u011bma a\u017e t\u0159emi m\u011bs\u00edci, u\u017e za\u010d\u00ednaj\u00ed b\u00fdt zastaral\u00e9. <\/p>\n<p><\/p>\n<p>N\u011bkter\u00e9 probl\u00e9my, kter\u00e9 jsme \u0159e\u0161ili, jsou u\u017e mo\u017en\u00e1 vy\u0159e\u0161eny standardn\u00edmi prost\u0159edky.<\/p>\n<p><\/p>\n<p>Velmi bych cht\u011bl pokra\u010dovat d\u00e1l a zam\u011b\u0159it se p\u0159\u00edmo na orchestrace.<\/p>\n<p><\/p>\n<p>Jedn\u00edm z p\u0159\u00edklad\u016f je vestav\u011bn\u00fd mechanismus Dockeru nazvan\u00fd Docker Swarm, kter\u00fd je dod\u00e1v\u00e1n v z\u00e1kladu. R\u00e1d bych spustil n\u011bco v produkci na z\u00e1klad\u011b technologie Docker Swarm.<\/p>\n<p><\/p>\n<p>Generov\u00e1n\u00ed kontejner\u016f zt\u011b\u017euje pr\u00e1ci s protokoly. Te\u010f jsou protokoly izolovan\u00e9. Jsou rozpt\u00fdlen\u00e9 mezi kontejnery. Jedn\u00edm z \u00fakol\u016f je ud\u011blat pohodln\u00fd p\u0159\u00edstup k protokol\u016fm prost\u0159ednictv\u00edm webov\u00e9ho rozhran\u00ed.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Proces v\u00fdvoje a testov\u00e1n\u00ed s Docker a Gitlab CI\" src=\"\/wp-content\/uploads\/2019\/04\/cff8c72dd8af7de1fa0227601bd1d69c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Zdroj: <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.3 - 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\/cs\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\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\/cs\/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\udd47 Proces v\u00fdvoje a testov\u00e1n\u00ed s Dockerem a Gitlab CI | ProHoster","description":"Doporu\u010duji se sezn\u00e1mit s p\u0159episem p\u0159edn\u00e1\u0161ky Alexandra Sigacheva z Inventosu \"Proces v\u00fdvoje a testov\u00e1n\u00ed s Dockerem + Gitlab CI\". Ti, kte\u0159\u00ed teprve za\u010d\u00ednaj\u00ed implementovat proces v\u00fdvoje.","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/protsess-razrabotki-i-testirovaniya-s-docker-i-gitlab-ci","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","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\/cs\/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\/cs\/wp-json\/wp\/v2\/posts\/32526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=32526"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/32526\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/24326"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=32526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=32526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=32526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}