{"id":40596,"date":"2020-02-02T10:38:43","date_gmt":"2020-02-02T07:38:43","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker"},"modified":"2020-02-02T10:38:43","modified_gmt":"2020-02-02T07:38:43","slug":"razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","title":{"rendered":"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/c8f98efef30babe012d23dd82a01c13b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Na pocz\u0105tek troch\u0119 teorii. Czym jest <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">The Twelve-Factor App<\/a><\/noindex>?<\/h3>\n<p>\nM\u00f3wi\u0105c prosto, jest to dokument maj\u0105cy na celu uproszczenie opracowywania aplikacji SaaS, pomagaj\u0105cy tym, \u017ce informuje programist\u00f3w i in\u017cynier\u00f3w DevOps o problemach oraz praktykach, kt\u00f3re najcz\u0119\u015bciej wyst\u0119powa\u0142y w opracowywaniu nowoczesnych aplikacji. <\/p>\n<p>Dokument ten zosta\u0142 opracowany przez tw\u00f3rc\u00f3w platformy Heroku.<\/p>\n<p>Metodyka dwunastu czynnik\u00f3w (The Twelve-Factor App) mo\u017ce by\u0107 stosowana w aplikacjach napisanych w ka\u017cdym j\u0119zyku programowania i wykorzystuj\u0105cych dowolne kombinacje us\u0142ug zewn\u0119trznych (backing services) (bazy danych, kolejki komunikat\u00f3w, pami\u0119ci podr\u0119czne itp.).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Kr\u00f3tko o samych czynnikach, na kt\u00f3rych oparta jest ta metodyka:<\/h3>\n<p><\/p>\n<ol>\n<li><b>Baza kodu<\/b> \u2013 Jedna baza kodu, monitorowana w systemie kontroli wersji \u2013 wiele wdro\u017ce\u0144 <\/li>\n<li><b>Zale\u017cno\u015bci<\/b> \u2013 Wyra\u017anie deklaruj i izoluj zale\u017cno\u015bci<\/li>\n<li><b>Konfiguracja<\/b> \u2013 Przechowuj konfiguracj\u0119 w \u015brodowisku wykonawczym<\/li>\n<li><b>Us\u0142ugi zewn\u0119trzne (Backing Services)<\/b> \u2013 Traktuj us\u0142ugi zewn\u0119trzne (backing services) jako zasoby do pod\u0142\u0105czenia<\/li>\n<li><b>Budowanie, wydanie, wykonanie<\/b> \u2013 \u015aci\u015ble oddzielaj etapy budowy i wykonania<\/li>\n<li><b>Procesy<\/b> \u2013 Uruchamiaj aplikacj\u0119 jako jeden lub kilka proces\u00f3w bez stan\u00f3w wewn\u0119trznych (stateless) <\/li>\n<li><b>Przypisanie portu (Port binding)<\/b> \u2013 Eksportuj us\u0142ugi poprzez przypisanie port\u00f3w <\/li>\n<li><b>R\u00f3wnoleg\u0142o\u015b\u0107<\/b> \u2013 Skaluj aplikacj\u0119 za pomoc\u0105 proces\u00f3w <\/li>\n<li><b>Usuwalno\u015b\u0107 (Disposability)<\/b> \u2013 Maksymalizuj niezawodno\u015b\u0107 dzi\u0119ki szybkiemu uruchamianiu i prawid\u0142owemu zako\u0144czeniu pracy <\/li>\n<li><b>Paralelizm rozwijania\/pracy aplikacji<\/b> \u2013 Utrzymuj \u015brodowiska rozwoju, wdro\u017cenia wst\u0119pnego (staging) oraz produkcji maksymalnie zbli\u017cone do siebie <\/li>\n<li><b>Logi (Logs)<\/b> \u2013 Traktuj logi jako strumie\u0144 zdarze\u0144<\/li>\n<li><b>Zadania administracyjne<\/b> \u2013 Wykonuj zadania administracyjne\/zarz\u0105dzaj\u0105ce za pomoc\u0105 jednorazowych proces\u00f3w <\/li>\n<\/ol>\n<p>\n<b>Wi\u0119cej informacji o 12 czynnikach mo\u017cesz znale\u017a\u0107 w nast\u0119puj\u0105cych zasobach:<\/b><\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">Oficjalne \u017ar\u00f3d\u0142o<\/a><\/noindex> \u2014 obowi\u0105zkowe do przeczytania<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/258739\/\">Artyku\u0142 na habr. Aplikacja dwunastu czynnik\u00f3w \u2014 The Twelve-Factor App<\/a><\/noindex> \u2014 oficjalne t\u0142umaczenie<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460363\/\">Artyku\u0142 na habr. 7 brakuj\u0105cych czynnik\u00f3w w podej\u015bciu 12 Factor App<\/a><\/noindex> \u2014 \u015bwie\u017ce spojrzenie na 12 czynnik\u00f3w w celu ich udoskonalenia.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Czym jest wdro\u017cenie Blue-Green?<\/h3>\n<p>\nWdro\u017cenie Blue-Green to spos\u00f3b dostarczania aplikacji na <b>production<\/b> w taki spos\u00f3b, \u017ce klient ko\u0144cowy nie zauwa\u017ca \u017cadnych zmian z jego strony. Innymi s\u0142owy, wdra\u017canie aplikacji bez przestoj\u00f3w <b>downtime<\/b>.<\/p>\n<p>Klasyczny schemat BG Deploy wygl\u0105da tak, jak pokazano na poni\u017cszym obrazku. <\/p>\n<p><img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/8252356ac93ce40b248ab27982754985.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Na pocz\u0105tku s\u0105 2 fizyczne serwery z absolutnie identycznym kodem, aplikacj\u0105 i projektem oraz router (balanser). <\/li>\n<li>Router pocz\u0105tkowo kieruje wszystkie \u017c\u0105dania na jeden z serwer\u00f3w (<b>alfa<\/b>). <\/li>\n<li>W momencie, gdy trzeba zn\u00f3w przeprowadzi\u0107 wydanie, ca\u0142y projekt jest aktualizowany na drugim serwerze (<b>niebieski<\/b>), kt\u00f3ry w danym momencie nie obs\u0142uguje \u017cadnych \u017c\u0105da\u0144. <\/li>\n<li>Po tym, jak kod na <b>niebieskim<\/b> serwerze zostanie ca\u0142kowicie zaktualizowany, router otrzymuje polecenie, aby prze\u0142\u0105czy\u0107 si\u0119 na <b>zielony<\/b> na <b>niebieski<\/b> serwer. <\/li>\n<li>Teraz wszyscy klienci widz\u0105 efekty pracy kodu z <b>niebieskiego<\/b> . <\/li>\n<li> Przez jaki\u015b czas <b>alfa<\/b> serwer s\u0142u\u017cy jako kopia zapasowa na wypadek nieudanej aktualizacji na <b>niebieski<\/b> serwer i w przypadku niepowodzenia i b\u0142\u0119d\u00f3w, router prze\u0142\u0105cza strumie\u0144 u\u017cytkownik\u00f3w z powrotem na <b>alfa<\/b> serwer ze star\u0105 stabiln\u0105 wersj\u0105, a nowy kod idzie do poprawki i testowania.<\/li>\n<li>Na ko\u0144cu procesu, w ten sam spos\u00f3b aktualizowany jest <b>alfa<\/b> serwer. A po jego aktualizacji, router prze\u0142\u0105cza strumie\u0144 \u017c\u0105da\u0144 z powrotem na <b>alfa<\/b> serwer.<\/li>\n<\/ul>\n<p>\nTo wszystko wygl\u0105da bardzo dobrze i na pierwszy rzut oka nie powinno by\u0107 z tym \u017cadnych problem\u00f3w.<br \/>\nJednak poniewa\u017c \u017cyjemy w nowoczesnym \u015bwiecie, opcja z fizycznym prze\u0142\u0105cznikiem, jak przedstawiono w klasycznym schemacie, nam nie odpowiada. Na razie zapisz t\u0119 informacj\u0119, wr\u00f3cimy do niej p\u00f3\u017aniej.<\/p>\n<h3>Z\u0142e i dobre porady<\/h3>\n<p>\n<i>Zrzeczenie si\u0119 odpowiedzialno\u015bci<\/i>: W poni\u017cszych przyk\u0142adach podano narz\u0119dzia\/metodologie, kt\u00f3re ja stosuj\u0119, mo\u017cesz u\u017cywa\u0107 absolutnie dowolnych alternatyw o podobnych funkcjach. <\/p>\n<p>Wi\u0119kszo\u015b\u0107 przyk\u0142ad\u00f3w b\u0119dzie w ten czy inny spos\u00f3b \u0142\u0105czy\u0107 si\u0119 z web developmentem (to niespodzianka), z PHP i Dockerem.<\/p>\n<p>W punktach poni\u017cej znajduje si\u0119 proste praktyczne opisanie zastosowania czynnik\u00f3w na konkretnych przyk\u0142adach, je\u015bli chcesz uzyska\u0107 wi\u0119cej teorii na ten temat, zajrzyj do \u017ar\u00f3de\u0142 podlinkowanych powy\u017cej. <\/p>\n<h4>1. Baza kodowa<\/h4>\n<p>\nU\u017cywaj FTP i FileZilla, przesy\u0142aj\u0105c pliki na serwery po jednym, nie przechowuj kodu nigdzie poza serwerem produkcyjnym.<\/p>\n<p>W projekcie zawsze powinna by\u0107 jednolita baza kodowa, czyli ca\u0142y kod pochodzi z jednego miejsca. <b>Gitem<\/b> repozytori\u00f3w. Serwery (production, staging, test1, test2 ...) wykorzystuj\u0105 kod z ga\u0142\u0119zi jednego wsp\u00f3lnego repozytorium. W ten spos\u00f3b osi\u0105gamy sp\u00f3jno\u015b\u0107 kodu.<\/p>\n<h4>2. Zale\u017cno\u015bci<\/h4>\n<p>\nPobieraj wszystkie biblioteki w folderach bezpo\u015brednio do katalogu g\u0142\u00f3wnego projektu. Aktualizacje wykonuj po prostu przenosz\u0105c nowy kod do folderu z aktualn\u0105 wersj\u0105 biblioteki. Instaluj wszystkie niezb\u0119dne narz\u0119dzia bezpo\u015brednio na serwerze hostuj\u0105cym, na kt\u00f3rym dzia\u0142a jeszcze 20 us\u0142ug.<\/p>\n<p>Projekt zawsze powinien mie\u0107 wyra\u017anie okre\u015blon\u0105 list\u0119 zale\u017cno\u015bci (pod zale\u017cno\u015bciami rozumiem r\u00f3wnie\u017c \u015brodowisko). Wszystkie zale\u017cno\u015bci powinny by\u0107 wyra\u017anie zdefiniowane i izolowane. <br \/>\nNa przyk\u0142ad we\u017amy <b>Composer<\/b> i <b>Docker<\/b>.<\/p>\n<p><b>Composer<\/b> \u2014 mened\u017cer pakiet\u00f3w, kt\u00f3ry umo\u017cliwia instalacj\u0119 bibliotek PHP. Composer pozwala na jednoznaczne lub elastyczne okre\u015blenie wersji i ich jednoznaczn\u0105 definicj\u0119. Na serwerze mo\u017ce znajdowa\u0107 si\u0119 20 r\u00f3\u017cnych projekt\u00f3w, a ka\u017cdy z nich b\u0119dzie mia\u0142 swoj\u0105 w\u0142asn\u0105 list\u0119 pakiet\u00f3w i bibliotek, niezale\u017cn\u0105 od innych.<\/p>\n<p><b>Docker<\/b> \u2014 narz\u0119dzie, kt\u00f3re pozwala definiowa\u0107 i izolowa\u0107 \u015brodowisko, w kt\u00f3rym b\u0119dzie dzia\u0142a\u0107 aplikacja. W zwi\u0105zku z tym, podobnie jak w przypadku composera, ale w bardziej dog\u0142\u0119bny spos\u00f3b, mo\u017cemy okre\u015bli\u0107, na czym dzia\u0142a aplikacja. Wybra\u0107 konkretn\u0105 wersj\u0119 PHP, zainstalowa\u0107 tylko niezb\u0119dne pakiety do dzia\u0142ania projektu, nie dodaj\u0105c nic zb\u0119dnego. A co najwa\u017cniejsze, nie koliduj\u0105c z pakietami i \u015brodowiskiem maszyny hostuj\u0105cej i innych projekt\u00f3w. To znaczy, wszystkie projekty na serwerze dzia\u0142aj\u0105ce przez Docker mog\u0105 korzysta\u0107 z absolutnie dowolnego zestawu pakiet\u00f3w i z zupe\u0142nie r\u00f3\u017cnych \u015brodowisk.<\/p>\n<h4>3. Konfiguracja<\/h4>\n<p>\nPrzechowuj konfiguracje jako sta\u0142e bezpo\u015brednio w kodzie. Oddzielne sta\u0142e dla serwera testowego, oddzielne dla produkcji. Powi\u0105\u017c dzia\u0142anie aplikacji z zale\u017cno\u015bci\u0105 od \u015brodowiska bezpo\u015brednio w logice biznesowej projektu, u\u017cywaj\u0105c konstrukcji if else.<\/p>\n<p><b>Konfiguracje<\/b> \u2014 to jedyna rzecz, kt\u00f3ra powinna r\u00f3\u017cni\u0107 wdro\u017cenia projektu (deployment). W idealnym przypadku konfiguracje powinny by\u0107 przekazywane za pomoc\u0105 zmiennych \u015brodowiskowych (env vars). <\/p>\n<p>Oznacza to, \u017ce nawet je\u015bli b\u0119dziesz przechowywa\u0142 kilka plik\u00f3w konfiguracyjnych .config.prod, .config.local i zmienia\u0142 ich nazwy w momencie wdra\u017cania na .config (g\u0142\u00f3wny plik konfiguracyjny, z kt\u00f3rego aplikacja odczytuje dane) \u2014 to b\u0119dzie niew\u0142a\u015bciwe podej\u015bcie, gdy\u017c w takim przypadku informacje z konfiguracji b\u0119d\u0105 og\u00f3lnie dost\u0119pne wszystkim programistom aplikacji, a dane z serwera produkcyjnego b\u0119d\u0105 skompromitowane. Wszystkie konfiguracje powinny by\u0107 przechowywane bezpo\u015brednio w systemie wdra\u017cania (CI\/CD) i generowane dla r\u00f3\u017cnych \u015brodowisk z r\u00f3\u017cnymi warto\u015bciami potrzebnymi dla konkretnego \u015brodowiska w\u0142a\u015bnie w momencie wdro\u017cenia.<\/p>\n<h4>4. Zewn\u0119trzne us\u0142ugi (Backing Services)<\/h4>\n<p>\nMocno zwi\u0105zuj si\u0119 ze \u015brodowiskiem, u\u017cywaj r\u00f3\u017cnych po\u0142\u0105cze\u0144 dla tych samych us\u0142ug w okre\u015blonych \u015brodowiskach.<\/p>\n<p>W rzeczywisto\u015bci ten punkt mocno pokrywa si\u0119 z punktem o konfiguracjach, poniewa\u017c bez tego punktu nie da si\u0119 stworzy\u0107 normalnych danych konfiguracyjnych, a w og\u00f3le mo\u017cliwo\u015b\u0107 konfigurowania zaniknie.<\/p>\n<p>Wszystkie po\u0142\u0105czenia z zewn\u0119trznymi us\u0142ugami, takimi jak serwery kolejki, bazy danych, us\u0142ugi cache musz\u0105 by\u0107 jednorodne zar\u00f3wno dla lokalnego \u015brodowiska, jak i zewn\u0119trznego \/ produkcyjnego. Innymi s\u0142owy, mog\u0119 w ka\u017cdej chwili, zmieniaj\u0105c ci\u0105g po\u0142\u0105czenia, zast\u0105pi\u0107 odwo\u0142ania do bazy #1 na baz\u0119 #2 bez zmiany kodu aplikacji. Albo przewiduj\u0105c przyk\u0142ad, \u017ce podczas skalowania us\u0142ugi, nie b\u0119dziesz musia\u0142 podawa\u0107 po\u0142\u0105czenia w specjalny spos\u00f3b dla dodatkowego serwera cache.<\/p>\n<h4>5. Budowanie, wydanie, wykonanie<\/h4>\n<p>\nMiej na serwerze tylko ostateczn\u0105 wersj\u0119 kodu, bez mo\u017cliwo\u015bci cofni\u0119cia wydania. Nie nale\u017cy zape\u0142nia\u0107 przestrzeni dyskowej. Kto my\u015bli, \u017ce mo\u017ce wypu\u015bci\u0107 kod na produkcj\u0119 z b\u0142\u0119dem, jest z\u0142ym programist\u0105!<\/p>\n<p>Wszystkie etapy wdro\u017cenia powinny by\u0107 od siebie oddzielone.<\/p>\n<p>Miej mo\u017cliwo\u015b\u0107 powrotu. Wydawaj wersje z zachowaniem starych kopii aplikacji (ju\u017c skompilowanych i gotowych do u\u017cycia) w szybkim dost\u0119pie, aby w przypadku b\u0142\u0119d\u00f3w m\u00f3c przywr\u00f3ci\u0107 wcze\u015bniejsz\u0105 wersj\u0119. To znaczy, \u017ce jest folder <i>releases<\/i> i folder <i>pr\u0105d<\/i>, a po pomy\u015blnym wdro\u017ceniu i kompilacji folder <i>pr\u0105d<\/i> jest powi\u0105zany symboliczny link z nowym wydaniem, kt\u00f3re le\u017cy w \u015brodku <i>releases<\/i> z umown\u0105 nazw\u0105 numeru wydania. <\/p>\n<p>Tutaj przypominamy sobie o Blue-Green deployment, kt\u00f3ry umo\u017cliwia nie tylko prze\u0142\u0105czanie mi\u0119dzy kodem, ale tak\u017ce prze\u0142\u0105czanie mi\u0119dzy wszystkimi zasobami, a nawet \u015brodowiskami z mo\u017cliwo\u015bci\u0105 przywr\u00f3cenia wszystkiego do poprzedniego stanu.<\/p>\n<h4>6. Procesy<\/h4>\n<p>\nPrzechowuj dane o stanach aplikacji bezpo\u015brednio w samej aplikacji. U\u017cywaj sesji w pami\u0119ci operacyjnej samej aplikacji. U\u017cywaj jak najwi\u0119cej wsp\u00f3lnych zewn\u0119trznych us\u0142ug. Uzale\u017cniaj to od faktu, \u017ce aplikacja mo\u017ce mie\u0107 tylko jeden proces i nie dopuszczaj mo\u017cliwo\u015bci skalowania.<\/p>\n<p>Je\u015bli chodzi o sesje, przechowuj dane wy\u0142\u0105cznie w pami\u0119ci podr\u0119cznej kontrolowanej przez zewn\u0119trzne us\u0142ugi (memcached, redis), w ten spos\u00f3b nawet je\u015bli masz uruchomionych 20 proces\u00f3w aplikacji, to ka\u017cda z nich, zwracaj\u0105c si\u0119 do pami\u0119ci podr\u0119cznej, mo\u017ce kontynuowa\u0107 prac\u0119 z klientem w tym samym stanie, w jakim u\u017cytkownik by\u0142 pracuj\u0105c z aplikacj\u0105 w innym procesie. Przy takim podej\u015bciu okazuje si\u0119, \u017ce niezale\u017cnie od tego, ile kopii zewn\u0119trznych us\u0142ug u\u017cywasz, wszystko b\u0119dzie dzia\u0142a\u0107 poprawnie i bez problem\u00f3w z dost\u0119pem do danych.<\/p>\n<h4>7. Wi\u0105zanie port\u00f3w (Port binding)<\/h4>\n<p>\nTylko serwer WWW powinien wiedzie\u0107, jak pracowa\u0107 z zewn\u0119trznymi us\u0142ugami. A najlepiej by\u0142oby uruchomi\u0107 zewn\u0119trzne us\u0142ugi bezpo\u015brednio w serwerze webowym. Na przyk\u0142ad jako modu\u0142 PHP w Apache.<br \/>\nWszystkie twoje us\u0142ugi powinny by\u0107 dost\u0119pne dla siebie nawzajem poprzez odwo\u0142anie do jakiego\u015b adresu i portu (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), to znaczy z nginx mog\u0119 uzyska\u0107 dost\u0119p zar\u00f3wno do php-fpm, jak i do postgres, a z php-fpm do postgres i nginx, i w\u0142a\u015bciwie z ka\u017cdej us\u0142ugi mog\u0119 uzyska\u0107 dost\u0119p do innej us\u0142ugi. W ten spos\u00f3b \u017cywotno\u015b\u0107 jednej us\u0142ugi nie jest uzale\u017cniona od \u017cywotno\u015bci innej us\u0142ugi.<\/p>\n<h4>8. R\u00f3wnoleg\u0142o\u015b\u0107<\/h4>\n<p>\nPracuj z jednym procesem, bo nagle kilka proces\u00f3w mo\u017ce nie umie\u0107 ze sob\u0105 wsp\u00f3\u0142pracowa\u0107! <\/p>\n<p>Pozostaw mo\u017cliwo\u015b\u0107 skalowania. \u015awietnie do tego nadaje si\u0119 docker swarm. <br \/>\nDocker Swarm to narz\u0119dzie do tworzenia i zarz\u0105dzania klastrami kontener\u00f3w zar\u00f3wno mi\u0119dzy r\u00f3\u017cnymi maszynami, jak i setkami kontener\u00f3w na jednej maszynie.<\/p>\n<p>Dzi\u0119ki swarmowi mog\u0119 okre\u015bli\u0107, ile zasob\u00f3w przeznaczam na ka\u017cdy proces oraz ile proces\u00f3w tej samej us\u0142ugi b\u0119d\u0119 uruchamia\u0107. Wewn\u0119trzny balansuj\u0105cy, przyjmuj\u0105c dane na przypisanym porcie, automatycznie przekieruje je do proces\u00f3w. W ten spos\u00f3b, w przypadku wzrostu obci\u0105\u017cenia serwera, mog\u0119 doda\u0107 wi\u0119cej proces\u00f3w, tym samym zmniejszaj\u0105c obci\u0105\u017cenie poszczeg\u00f3lnych z nich.<\/p>\n<h4>9. Utylizowalno\u015b\u0107 (Disposability)<\/h4>\n<p>\nNie u\u017cywaj kolejek do pracy z procesami i danymi. Zatrzymanie jednego procesu powinno wp\u0142ywa\u0107 na dzia\u0142anie ca\u0142ej aplikacji. Je\u015bli jedna us\u0142uga spadnie \u2014 spada wszystko.<\/p>\n<p>Ka\u017cdy proces i us\u0142uga mog\u0105 by\u0107 wy\u0142\u0105czone w ka\u017cdym momencie, a to nie powinno wp\u0142ywa\u0107 na inne us\u0142ugi (mowa oczywi\u015bcie nie o tym, \u017ce us\u0142uga b\u0119dzie niedost\u0119pna dla innej, ale o tym, \u017ce inna us\u0142uga nie wy\u0142\u0105czy si\u0119 w \u015blad za t\u0105). Wszystkie procesy musz\u0105 ko\u0144czy\u0107 si\u0119 \u0142agodnie, tak aby przy ich zako\u0144czeniu dane nie ucierpia\u0142y, a przy nast\u0119pnym uruchomieniu system dzia\u0142a\u0142 poprawnie. To znaczy, \u017ce nawet w przypadku awaryjnego zako\u0144czenia, dane nie powinny zosta\u0107 uszkodzone (tu sprawdzi si\u0119 mechanizm transakcji, zapytania do bazy danych dzia\u0142aj\u0105 tylko w grupach, i je\u015bli kt\u00f3rekolwiek zapytanie z grupy nie zosta\u0142o wykonane lub wykonano je z b\u0142\u0119dem, \u017cadne inne zapytanie z grupy r\u00f3wnie\u017c w rzeczywisto\u015bci nie jest realizowane).<\/p>\n<h4>10. Parzysto\u015b\u0107 rozwoju \/ pracy aplikacji<\/h4>\n<p>\nProdukcja, staging i lokalna wersja aplikacji powinny by\u0107 r\u00f3\u017cne. Na produkcji mamy framework Yii Lite, a lokalnie Yii, aby na produkcji dzia\u0142a\u0142o szybciej!<\/p>\n<p>W rzeczywisto\u015bci wszystkie wdro\u017cenia i praca z kodem powinny odbywa\u0107 si\u0119 w niemal identycznym \u015brodowisku (nie m\u00f3wi\u0119 tutaj o fizycznym sprz\u0119cie). R\u00f3wnie\u017c kod na produkcji powinien by\u0107 w razie potrzeby wdro\u017cony przez ka\u017cdego pracownika zespo\u0142u deweloperskiego, a nie przez specjalnie przeszkolony dzia\u0142 devops, kt\u00f3ry tylko dzi\u0119ki szczeg\u00f3lnej sile mo\u017ce uruchomi\u0107 aplikacj\u0119 w produkcji.<\/p>\n<p>W tym r\u00f3wnie\u017c pomaga nam Docker. Przy przestrzeganiu wszystkich poprzednich punkt\u00f3w, u\u017cycie dockera sprawi, \u017ce proces wdra\u017cania \u015brodowiska zar\u00f3wno na produkcji, jak i na lokalnej maszynie sprowadzi si\u0119 do wprowadzenia jednej lub dw\u00f3ch komend.<\/p>\n<h4>11. Rejestrowanie (Logs)<\/h4>\n<p>\nLogi zapisujemy w plikach i bazie danych! Pliki i baza danych log\u00f3w nie s\u0105 czyszczone. Po prostu kupimy dysk twardy na 9000 Petabajt\u00f3w i b\u0119dzie ok.<\/p>\n<p>Wszystkie logi nale\u017cy traktowa\u0107 jako strumie\u0144 zdarze\u0144. Sama aplikacja nie powinna zajmowa\u0107 si\u0119 przetwarzaniem log\u00f3w. Logi powinny by\u0107 wysy\u0142ane do stdout lub przesy\u0142ane protoko\u0142em takim jak udp, aby praca aplikacji z logami nie stwarza\u0142a \u017cadnych problem\u00f3w. Do tego celu doskonale nadaje si\u0119 graylog. Graylog, przyjmuj\u0105c wszystkie logi przez udp (w tym protokole nie jest wymagane oczekiwanie na potwierdzenie odbioru pakietu), nie zak\u0142\u00f3ca w \u017caden spos\u00f3b dzia\u0142ania aplikacji i zajmuje si\u0119 tylko strukturyzacj\u0105 i przetwarzaniem log\u00f3w. Logika aplikacji nie zmienia si\u0119 przy u\u017cyciu takich podej\u015b\u0107.<\/p>\n<h4>12. Zadania administracyjne<\/h4>\n<p>\nAby zaktualizowa\u0107 dane, baz\u0119 danych itp., nale\u017cy u\u017cy\u0107 osobno utworzonego endpointa w API. Wykonanie go dwa razy z rz\u0119du mo\u017ce spowodowa\u0107, \u017ce wszystko si\u0119 zdubluje. Ale wy przecie\u017c nie jeste\u015bcie g\u0142upcami, wi\u0119c nie naci\u015bniecie dwa razy, a migracje s\u0105 nam niepotrzebne.<\/p>\n<p>Wszystkie zadania administracyjne powinny by\u0107 wykonywane w tym samym \u015brodowisku, co ca\u0142y kod, na poziomie wersji. To znaczy, \u017ce je\u015bli musimy zmieni\u0107 struktur\u0119 bazy danych, nie b\u0119dziemy tego robi\u0107 r\u0119cznie, zmieniaj\u0105c nazwy kolumn i dodaj\u0105c nowe przez jakie\u015b wizualne narz\u0119dzia do zarz\u0105dzania baz\u0105 danych. Na takie rzeczy tworzymy osobne skrypty \u2014 migracje, kt\u00f3re s\u0105 wykonywane wsz\u0119dzie i na wszystkich \u015brodowiskach w spos\u00f3b jednolity i zrozumia\u0142y. Dla wszystkich innych zada\u0144, takich jak wype\u0142nianie projektu danymi, nale\u017cy stosowa\u0107 podobne metodologie.<\/p>\n<h3>Przyk\u0142ad implementacji w PHP, Laravel, Laradock, Docker-Compose<\/h3>\n<p>\nP.S. Wszystkie przyk\u0142ady zosta\u0142y zrobione na MacOS. Wi\u0119kszo\u015b\u0107 z nich jest odpowiednia r\u00f3wnie\u017c dla Linuxa. U\u017cytkownicy Windows, przepraszam, ale od lat nie pracowa\u0142em z Windowsem.<\/p>\n<p>Wyobra\u017amy sobie sytuacj\u0119, w kt\u00f3rej na naszym PC nie jest zainstalowana \u017cadna wersja PHP ani nic innego. <br \/>\nInstalujemy najnowsze wersje dockera i docker-compose. (mo\u017cna to znale\u017a\u0107 w internecie)<\/p>\n<pre><code class=\"bash\">docker -v &amp;&amp; \ndocker-compose -v\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/d9e77c47eef486befb6ebd8118403d13.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n1. Instalujemy <noindex><a rel=\"nofollow\" href=\"https:\/\/laradock.io\/\">Laradock<\/a><\/noindex><\/p>\n<pre><code class=\"bash\">git clone https:\/\/github.com\/Laradock\/laradock.git &amp;&amp; \nls\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/67b3214d9a5cff4596c4914ea6e199c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJe\u015bli chodzi o Laradock, to mog\u0119 powiedzie\u0107, \u017ce to bardzo fajna rzecz, w kt\u00f3rej zebrano wiele kontener\u00f3w i pomocniczych narz\u0119dzi. Jednak\u017ce u\u017cywanie Laradock bez modyfikacji na produkcji \u2014 nie poleca\u0142bym ze wzgl\u0119du na jego nadmiarowo\u015b\u0107. Lepiej stworzy\u0107 w\u0142asne kontenery opieraj\u0105c si\u0119 na przyk\u0142adach z Laradock, poniewa\u017c b\u0119dzie to bardziej optymalne, gdy\u017c nikt nie potrzebuje wszystkiego, co tam jest, jednocze\u015bnie.<\/p>\n<p>2. Konfigurujemy Laradock do dzia\u0142ania naszej aplikacji.<\/p>\n<pre><code class=\"bash\">cd laradock &amp;&amp; \ncp env-example .env\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/df8107e1be933cc955be8ca5066f22f2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.1. Otwieramy katalog habr (g\u0142\u00f3wna folder, w kt\u00f3rym sklonowano laradock) w dowolnym edytorze. (W moim przypadku PHPStorm)<\/p>\n<p>Na tym etapie nadajemy tylko nazw\u0119 projektowi.<\/p>\n<p><img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/f6026fd04130590539e0945db30ec0dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.2. Uruchamiamy obraz workspace. (W twoim przypadku obrazy b\u0119d\u0105 si\u0119 budowa\u0107 przez jaki\u015b czas)<br \/>\nWorkspace to specjalnie przygotowany obraz do pracy z frameworkiem w imieniu programisty.<\/p>\n<p>Przechodzimy do kontenera za pomoc\u0105 <\/p>\n<pre><code class=\"bash\">docker-compose up -d workspace &amp;&amp; \ndocker-compose exec workspace bash\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/e839a5cd055b6c06c02cdd03a5054477.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.3. Instalujemy Laravel<\/p>\n<pre><code class=\"bash\">composer create-project --prefer-dist laravel\/laravel application<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/b21b3fc30ce1bec63aee43ab5fce53e3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.4. Po instalacji sprawdzamy, czy utworzono katalog z projektem, i zamykamy compose.<\/p>\n<pre><code class=\"bash\">ls\nexit\ndocker-compose down\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/e812f383138637656ec96804833cfc53.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.5. Wracamy do PHPStorm i ustawiamy poprawn\u0105 \u015bcie\u017ck\u0119 do naszego aplikacji laravel w pliku .env.<\/p>\n<p><img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/abb9a5694d01163960af5375767f331b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n3. Dodajemy ca\u0142y kod do Gita.<\/p>\n<p>W tym celu tworzymy repozytorium na Githubie (lub gdziekolwiek indziej). Przechodzimy w terminalu do katalogu habr i wykonujemy nast\u0119puj\u0105cy kod.<\/p>\n<pre><code class=\"bash\">echo \"# habr-12factor\" &gt;&gt; README.md\ngit init\ngit add README.md\ngit commit -m \"pierwsze zatwierdzenie\"\ngit remote add origin git@github.com:nzulfigarov\/habr-12factor.git # tutaj b\u0119dzie link do twojego repo\n git push -u origin master\ngit status\n<\/code><\/pre>\n<p>\nSprawdzamy, czy wszystko jest w porz\u0105dku. <\/p>\n<p><img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/cbcb770a95d91655bdaf727be79742ab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDla wygody polecam u\u017cywa\u0107 jakiego\u015b wizualnego interfejsu do Gita, w moim przypadku jest to <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gitkraken.com\/invite\/qXBXV9Wm\">GitKraken<\/a><\/noindex>. (tutaj link referencyjny)<\/p>\n<p>4. Uruchamiamy!<\/p>\n<p>Przed uruchomieniem upewnij si\u0119, \u017ce na porcie 80 i 443 nic nie jest zaj\u0119te.<\/p>\n<pre><code class=\"bash\">docker-compose up -d nginx php-fpm<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/f0bf0416e67b918e0966100e37c74454.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nW ten spos\u00f3b nasz projekt sk\u0142ada si\u0119 z 3 oddzielnych us\u0142ug:<\/p>\n<ul>\n<li>nginx - serwer WWW<\/li>\n<li>php-fpm - PHP do obs\u0142ugi \u017c\u0105da\u0144 z serwera WWW<\/li>\n<li>workspace - PHP dla programisty<\/li>\n<\/ul>\n<p>\nNa chwil\u0119 obecn\u0105 osi\u0105gn\u0119li\u015bmy to, \u017ce stworzyli\u015bmy aplikacj\u0119, kt\u00f3ra spe\u0142nia ju\u017c 4 punkty z 12, a mianowicie:<\/p>\n<p>1. <b>Baza kodu<\/b> \u2014 ca\u0142y kod znajduje si\u0119 w jednym repozytorium (drobna uwaga: by\u0107 mo\u017ce lepiej by\u0142oby umie\u015bci\u0107 dockera wewn\u0105trz projektu laravel, ale to nie jest zasadnicze).<\/p>\n<p>2. <b>Zale\u017cno\u015bci<\/b> \u2014 Wszystkie nasze zale\u017cno\u015bci s\u0105 wyra\u017anie zapisane w application\/composer.json i w ka\u017cdym Dockerfile ka\u017cdego kontenera.<\/p>\n<p>3. <b>Us\u0142ugi zewn\u0119trzne (Backing Services)<\/b> \u2014 Ka\u017cda z us\u0142ug (php-fpm, nginx, workspace) dzia\u0142a swoim \u017cyciem i jest pod\u0142\u0105czona z zewn\u0105trz, a podczas pracy z jedn\u0105 us\u0142ug\u0105, druga nie b\u0119dzie dotkni\u0119ta.<\/p>\n<p>4. <b>Procesy<\/b> \u2014 ka\u017cda us\u0142uga to jeden proces. Ka\u017cda z us\u0142ug nie przechowuje wewn\u0119trznego stanu.<\/p>\n<p>5.<b> Przypisanie portu (Port binding)<\/b><\/p>\n<pre><code class=\"bash\">docker ps\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/e6e3fa4a12a43d1bcd51992c424c1245.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJak widzimy, ka\u017cda us\u0142uga dzia\u0142a na swoim w\u0142asnym porcie i jest dost\u0119pna dla wszystkich innych us\u0142ug.<\/p>\n<p>6.<b> R\u00f3wnoleg\u0142o\u015b\u0107 <\/b><\/p>\n<p>Docker pozwala nam uruchamia\u0107 wiele proces\u00f3w tych samych us\u0142ug z automatycznym balansowaniem obci\u0105\u017cenia mi\u0119dzy nimi. <\/p>\n<p>Zatrzymajmy kontenery i uruchommy je z flag\u0105 <b>\u2014scale<\/b><\/p>\n<pre><code class=\"bash\">docker-compose down &amp;&amp; \ndocker-compose up -d --scale php-fpm=3 nginx php-fpm\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/f5d279b8a034512dd20024272c7f03b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJak widzimy, kontener php-fpm stworzy\u0142 kopie. Nie musimy nic zmienia\u0107 w pracy z tym kontenerem. Nadal b\u0119dziemy si\u0119 do niego zwraca\u0107 przez port 9000, a Docker reguluje obci\u0105\u017cenie mi\u0119dzy kontenerami.<\/p>\n<p>7. <b>Usuwalno\u015b\u0107 (Disposability)<\/b> \u2014 ka\u017cdy kontener mo\u017cna zabi\u0107 bez szkody dla innych. Zatrzymanie lub ponowne uruchomienie kontenera nie wp\u0142ynie na dzia\u0142anie aplikacji przy kolejnych uruchomieniach. Ka\u017cdy kontener mo\u017cna r\u00f3wnie\u017c uruchomi\u0107 w dowolnym momencie.<\/p>\n<p>8. <b>Paralelizm rozwijania\/pracy aplikacji<\/b> \u2014 wszystkie nasze \u015brodowiska s\u0105 identyczne. Uruchamiaj\u0105c system na serwerze w produkcji, nie b\u0119dziesz musia\u0142 nic zmienia\u0107 w swoich poleceniach. Wszystko b\u0119dzie dzia\u0142a\u0107 dok\u0142adnie tak samo na bazie Docker.<\/p>\n<p>9. <b>Logi (Logs)<\/b> \u2014 wszystkie logi w tych kontenerach wyp\u0142ywaj\u0105 na standardowe wyj\u015bcie i s\u0105 widoczne w konsoli Docker. (w tym przypadku, w rzeczywisto\u015bci, przy innych stworzonych kontenerach mo\u017ce by\u0107 inaczej, je\u015bli o to nie zadbasz)<\/p>\n<pre><code class=\"bash\"> docker-compose logs -f<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/67e275042b96f5270534466b426d4fdc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJednak pojawia si\u0119 problem, \u017ce warto\u015bci domy\u015blne w PHP i Nginx r\u00f3wnie\u017c zapisuj\u0105 logi do pliku. Aby dostosowa\u0107 si\u0119 do 12 zasad, konieczne jest <b>s\u0142owo kluczowe debugger; na bie\u017c\u0105cej stronie.<\/b> zapis log\u00f3w do pliku w konfiguracjach ka\u017cdego kontenera osobno.<\/p>\n<p>Docker daje r\u00f3wnie\u017c mo\u017cliwo\u015b\u0107 kierowania log\u00f3w nie tylko do stdout, ale tak\u017ce do takich narz\u0119dzi jak graylog, o kt\u00f3rym wspomnia\u0142em wcze\u015bniej. A w graylog mo\u017cemy operowa\u0107 logami jak tylko chcemy, a nasza aplikacja nie b\u0119dzie tego zauwa\u017ca\u0107.<\/p>\n<p>10. <b>Zadania administracyjne<\/b> \u2014 wszystkie zadania administracyjne s\u0105 rozwi\u0105zywane przez laravel dzi\u0119ki narz\u0119dziu artisan dok\u0142adnie tak, jak \u017cyczyliby sobie tw\u00f3rcy aplikacji 12-faktorowej.<\/p>\n<p>Na przyk\u0142ad poka\u017c\u0119, jak wykonuj\u0105 si\u0119 niekt\u00f3re polecenia.<br \/>\nWchodzimy do kontenera.<\/p>\n<pre><code class=\"bash\"> \ndocker-compose exec workspace bash\nphp artisan list\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/3d5fb5bc40b4b8b0cb225116c0f3d625.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTeraz mo\u017cemy skorzysta\u0107 z dowolnego polecenia. (zwr\u00f3\u0107 uwag\u0119, \u017ce nie konfigurowali\u015bmy bazy danych ani pami\u0119ci podr\u0119cznej, dlatego po\u0142owa polece\u0144 nie wykona si\u0119 poprawnie, poniewa\u017c s\u0105 one przeznaczone do pracy z pami\u0119ci\u0105 podr\u0119czn\u0105 i baz\u0105 danych).<\/p>\n<p><img decoding=\"async\" alt=\"Rozw\u00f3j aplikacji i Blue-Green deployment, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker\" src=\"\/wp-content\/uploads\/2020\/02\/6f84bb2ade2ade654d2c361c585edeae.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n11. <b>Konfiguracje<\/b> i 12. <b>Budowanie, wydanie, wykonanie<\/b><\/p>\n<p>Chcia\u0142em po\u015bwi\u0119ci\u0107 t\u0119 cz\u0119\u015b\u0107 Blue-Green Deployment, ale okaza\u0142o si\u0119 to zbyt rozbudowane na ten artyku\u0142. O tym napisz\u0119 oddzielny artyku\u0142. <\/p>\n<p>Kr\u00f3tko m\u00f3wi\u0105c, koncepcja opiera si\u0119 na systemach CI\/CD takich jak <b>Jenkins<\/b> i <b>Gitlab CI<\/b>. W obu mo\u017cna ustawia\u0107 zmienne \u015brodowiskowe zwi\u0105zane z konkretnym \u015brodowiskiem. W zwi\u0105zku z tym w tej sytuacji wykonywany b\u0119dzie punkt dotycz\u0105cy <b>Konfiguracji<\/b>.<\/p>\n<p>A punkt dotycz\u0105cy <b>Budowanie, wydanie, wykonanie<\/b> jest rozwi\u0105zywany przez wbudowane w obie narz\u0119dzia funkcje o nazwie <b>Pipeline<\/b>.<\/p>\n<p><b>Pipeline<\/b> umo\u017cliwia podzia\u0142 procesu wdra\u017cania na wiele etap\u00f3w, wyodr\u0119bniaj\u0105c etapy budowy, wydania i wykonywania. W Pipeline b\u0119dziesz m\u00f3g\u0142 tak\u017ce tworzy\u0107 kopie zapasowe, a w zasadzie cokolwiek innego. To narz\u0119dzie ma nieograniczony potencja\u0142.<\/p>\n<p>Kod aplikacji znajduje si\u0119 na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nzulfigarov\/habr-12factor\">Podr\u00f3\u017c, kt\u00f3r\u0105 przeszed\u0142em, okaza\u0142a si\u0119 fascynuj\u0105c\u0105 wypraw\u0105 w przesz\u0142o\u015b\u0107 i ciesz\u0119 si\u0119, \u017ce w ko\u0144cu znalaz\u0142em rozwi\u0105zanie. Poza tym:<\/a><\/noindex>.<br \/>\nNie zapomnij zainicjowa\u0107 submodu\u0142u przy klonowaniu tego repozytorium.<\/p>\n<p>P.S.: Wszystkie te podej\u015bcia mo\u017cna zastosowa\u0107 z dowolnymi innymi narz\u0119dziami i j\u0119zykami programowania. Najwa\u017cniejsze, aby zasada si\u0119 nie r\u00f3\u017cni\u0142a.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/480020\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 The Twelve-Factor App? \u041f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u044d\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043d\u044b\u0439 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 SaaS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0442\u0435\u043c \u0447\u0442\u043e, \u043e\u0441\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438 DevOps \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043e\u0432 \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0438\u0441\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b Heroku. \u041c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044f \u0434\u0432\u0435\u043d\u0430\u0434\u0446\u0430\u0442\u0438 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432(The Twelve-Factor App) \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043b\u044e\u0431\u043e\u043c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":40597,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-40596","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\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\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker\" \/>\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\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 Blue-Green deployment, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e The Twelve-Factor App \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043d\u0430 php \u0438 docker | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker\" \/>\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=\"2020-02-02T07:38:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-02T07:38:43+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\udd47Rozw\u00f3j aplikacji i wdra\u017canie Blue-Green, opieraj\u0105c si\u0119 na metodologii The Twelve-Factor App z przyk\u0142adami w php i docker | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","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\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 Blue-Green deployment, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e The Twelve-Factor App \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043d\u0430 php \u0438 docker | ProHoster","og:url":"https:\/\/prohoster.info\/pl\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","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":"2020-02-02T07:38:43+00:00","article:modified_time":"2020-02-02T07:38:43+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"40596","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:20:45","updated":"2022-09-27 22:57:35","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\/40596","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=40596"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/40596\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/40597"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=40596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=40596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=40596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}