{"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\/ro\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","title":{"rendered":"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/c8f98efef30babe012d23dd82a01c13b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Pentru \u00eenceput, un pic de teorie. Ce este <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">Aplica\u021bia \u00een Dou\u0103sprezece Factori<\/a><\/noindex>?<\/h3>\n<p>\nPe scurt, acesta este un document destinat s\u0103 simplifice dezvoltarea aplica\u021biilor SaaS, ajut\u00e2ndu-i pe dezvoltatori \u0219i inginerii DevOps s\u0103 \u00een\u021beleag\u0103 problemele \u0219i practicile care au fost \u00eent\u00e2lnite cel mai des \u00een dezvoltarea aplica\u021biilor moderne. <\/p>\n<p>Documentul este elaborat de dezvoltatorii platformei Heroku.<\/p>\n<p>Metodologia aplica\u021biei \u00een dou\u0103sprezece factori (The Twelve-Factor App) poate fi aplicat\u0103 aplica\u021biilor scrise \u00een orice limbaj de programare \u0219i care utilizeaz\u0103 orice combina\u021bii de servicii externe (backing services) (baze de date, cozi de mesaje, memorie cache etc.).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Iat\u0103 pe scurt factorii pe care se bazeaz\u0103 aceast\u0103 metodologie:<\/h3>\n<p><\/p>\n<ol>\n<li><b>Baza de cod<\/b> \u2013 O singur\u0103 baz\u0103 de cod, urm\u0103rit\u0103 \u00een sistemul de control al versiunilor, \u2013 multe desf\u0103\u0219ur\u0103ri <\/li>\n<li><b>Dependin\u021be<\/b> \u2013 Declara\u021bi \u0219i izola\u021bi clar dependen\u021bele<\/li>\n<li><b>Configura\u021bie<\/b> \u2013 P\u0103stra\u021bi configura\u021bia \u00een mediu de execu\u021bie<\/li>\n<li><b>Servicii externe (Backing Services)<\/b> \u2013 Considera\u021bi serviciile externe (backing services) ca resurse interconectabile<\/li>\n<li><b>Compilare, lansare, execu\u021bie<\/b> \u2013 Separa\u021bi strict etapele de compilare \u0219i execu\u021bie<\/li>\n<li><b>Procese<\/b> \u2013 Rula\u021bi aplica\u021bia ca unul sau mai multe procese f\u0103r\u0103 stare (stateless) <\/li>\n<li><b>Legarea de porturi (Port binding)<\/b> \u2013 Exporta\u021bi serviciile prin legarea de porturi <\/li>\n<li><b>Paralelism<\/b> \u2013 Scalarea aplica\u021biei prin procese <\/li>\n<li><b>Utilizabilitate (Disposability)<\/b> \u2013 Maximizeaz\u0103 fiabilitatea prin pornire rapid\u0103 \u0219i oprire corect\u0103 <\/li>\n<li><b>Paritatea dezvolt\u0103rii \/ rul\u0103rii aplica\u021biei<\/b> \u2013 Men\u021bine\u021bi mediile de dezvoltare, desf\u0103\u0219urare intermediar\u0103 (staging) \u0219i desf\u0103\u0219urare \u00een produc\u021bie c\u00e2t mai asem\u0103n\u0103toare <\/li>\n<li><b>Jurnalizare (Logs)<\/b> \u2013 Trata\u021bi jurnalul ca un flux de evenimente<\/li>\n<li><b>Sarcini administrative<\/b> \u2013 Executa\u021bi sarcini administrative \/ de gestionare prin procese unice <\/li>\n<\/ol>\n<p>\n<b>Mai multe informa\u021bii despre cei 12 factori pot fi ob\u021binute din urm\u0103toarele resurse:<\/b><\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">Sursa oficial\u0103<\/a><\/noindex> \u2013 de citit cu siguran\u021b\u0103<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/258739\/\">Articol pe habr. Aplica\u021bia \u00een dou\u0103sprezece factori \u2014 The Twelve-Factor App<\/a><\/noindex> \u2013 traducere oficial\u0103<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460363\/\">Articol pe habr. Cele 7 factori lips\u0103 \u00een abordarea aplica\u021biei \u00een 12 factori<\/a><\/noindex> \u2013 o nou\u0103 perspectiv\u0103 asupra celor 12 factori cu scopul de a-i \u00eembun\u0103t\u0103\u021bi.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Ce este implementarea Blue-Green?<\/h3>\n<p>\nImplementarea Blue-Green este o metod\u0103 de livrare a aplica\u021biei pe <b>produc\u021bie<\/b> astfel \u00eenc\u00e2t clientul final s\u0103 nu observe nicio schimbare din partea lui. Cu alte cuvinte, desf\u0103\u0219urarea aplica\u021biei cu zero <b>timp de nefunc\u021bionare<\/b>.<\/p>\n<p>Schema clasic\u0103 BG Deploy arat\u0103 a\u0219a cum este indicat \u00een imaginea de mai jos. <\/p>\n<p><img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/8252356ac93ce40b248ab27982754985.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>La \u00eenceput, exist\u0103 2 servere fizice cu un cod absolut identic, aplica\u021bie, proiect \u0219i exist\u0103 un router (\u00eemp\u0103r\u021bitor de sarcini). <\/li>\n<li>Routerul direc\u021bioneaz\u0103 ini\u021bial toate cererile c\u0103tre unul dintre servere (<b>verde<\/b>). <\/li>\n<li>\u00cen momentul \u00een care trebuie s\u0103 facem din nou un release, \u00eentreg proiectul este actualizat pe cealalt\u0103 server (<b>albastru<\/b>), care \u00een acel moment nu prelucreaz\u0103 nicio cerere. <\/li>\n<li>Dup\u0103 ce codul de pe <b>albastru<\/b> server este complet actualizat, routerului i se d\u0103 comanda c\u0103 trebuie s\u0103 comute de la <b>verde<\/b> pe <b>albastru<\/b> server. <\/li>\n<li>Acum to\u021bi clien\u021bii pot vedea rezultatul muncii codului de pe <b>serverul albastru.<\/b> O perioad\u0103, <\/li>\n<li> serverul serve\u0219te ca backup \u00een caz de un deploy ratat pe <b>verde<\/b> server \u0219i \u00een caz de e\u0219ec \u0219i buguri, routerul comuteaz\u0103 fluxul utilizatorilor \u00eenapoi pe <b>albastru<\/b> server cu vechea versiune stabil\u0103, iar noul cod este trimis pentru \u00eembun\u0103t\u0103\u021bire \u0219i testare. <b>verde<\/b> \u0218i la finalul procesului, la fel se actualizeaz\u0103<\/li>\n<li>serverul. \u0218i dup\u0103 actualizarea acestuia, routerul comuteaz\u0103 fluxul cererilor \u00eenapoi pe <b>verde<\/b> Arat\u0103 foarte bine \u0219i, la prima vedere, nu ar trebui s\u0103 existe probleme. <b>verde<\/b> server.<\/li>\n<\/ul>\n<p>\nDar, av\u00e2nd \u00een vedere c\u0103 tr\u0103im \u00een lumea modern\u0103, op\u021biunea cu comutarea fizic\u0103, a\u0219a cum este indicat \u00een schema clasic\u0103, nu ni se potrive\u0219te. Re\u021bine\u021bi informa\u021bia deocamdat\u0103, ne vom \u00eentoarce la ea mai t\u00e2rziu.<br \/>\nSfaturi bune \u0219i proaste<\/p>\n<h3>: \u00cen exemplele de mai jos sunt indicate utilitarele \/ metodologiile pe care le folosesc eu, pute\u021bi folosi absolut orice alternative cu func\u021bii similare.<\/h3>\n<p>\n<i>Declinarea<\/i>Cea mai mare parte din exemple va intersecta \u00een oarecare m\u0103sur\u0103 dezvoltarea web (surpriz\u0103), cu PHP \u0219i Docker. <\/p>\n<p>\u00cen punctele de mai jos este o descriere practic\u0103 simpl\u0103 a utiliz\u0103rii factorilor pe anumite exemple, dac\u0103 dori\u021bi mai mult\u0103 teorie pe aceast\u0103 tem\u0103, consulta\u021bi sursele de mai sus.<\/p>\n<p>1. Baza de cod <\/p>\n<h4>Folosi\u021bi FTP \u0219i FileZilla pentru a \u00eenc\u0103rca fi\u0219iere pe servere c\u00e2te unu, nu p\u0103stra\u021bi codul altundeva dec\u00e2t pe serverul de produc\u021bie.<\/h4>\n<p>\n\u00cen proiect ar trebui s\u0103 existe \u00eentotdeauna o baz\u0103 de cod unic\u0103, adic\u0103, tot codul provine dintr-o<\/p>\n<p>Git <b>Git<\/b> repository. Serverele (production, staging, test1, test2 &#8230;) folosesc cod din ramuri ale unui singur depozit comun. Astfel, ob\u021binem consisten\u021ba codului.<\/p>\n<h4>2. Dependen\u021be<\/h4>\n<p>\nDesc\u0103rca\u021bi toate bibliotecile \u00een foldere direct \u00een r\u0103d\u0103cina proiectului. Actualiz\u0103rile le face\u021bi prin simpla transferare a noului cod \u00een folderul cu versiunea curent\u0103 a bibliotecii. Instala\u021bi toate utilitarele direct pe serverul de hosting unde func\u021bioneaz\u0103 deja 20 de servicii.<\/p>\n<p>Proiectul trebuie s\u0103 aib\u0103 \u00eentotdeauna o list\u0103 clar\u0103 de dependen\u021be (sub dependen\u021be \u00een\u021beleg \u0219i mediu). Toate dependen\u021bele trebuie s\u0103 fie definite flagrant \u0219i izolate. <br \/>\nCa exemplu, s\u0103 lu\u0103m <b>Composer<\/b> \u0219i <b>Docker<\/b>.<\/p>\n<p><b>Composer<\/b> \u2014 un manager de pachete care permite instalarea bibliotecilor \u00een PHP. Composer ofer\u0103 posibilitatea de a specifica versiuni strict sau liber \u0219i de a le defini clar. Pe server pot exista 20 de proiecte diferite \u0219i fiecare va avea propria list\u0103 de pachete \u0219i biblioteci, independent de cel\u0103lalt.<\/p>\n<p><b>Docker<\/b> \u2014 un utilitar care permite definirea \u0219i izolarea mediu \u00een care va func\u021biona aplica\u021bia. A\u0219adar, similar cu composer, dar mai tematic, putem defini cu ce lucreaz\u0103 aplica\u021bia. Alege\u021bi o anumit\u0103 versiune PHP, instala\u021bi doar pachetele necesare pentru func\u021bionarea proiectului, f\u0103r\u0103 a ad\u0103uga nimic suplimentar. \u0218i cel mai important, f\u0103r\u0103 a se suprapune cu pachetele \u0219i mediul ma\u0219inii de hosting \u0219i al altor proiecte. Adic\u0103 toate proiectele de pe server care func\u021bioneaz\u0103 prin Docker pot folosi orice set de pachete \u0219i medii complet diferite.<\/p>\n<h4>3. Configurare<\/h4>\n<p>\nP\u0103stra\u021bi configura\u021biile ca constante direct \u00een cod. Constate separate pentru serverul de testare, separate pentru produc\u021bie. Lega\u021bi func\u021bionarea aplica\u021biei de mediu direct \u00een logica de business a proiectului folosind structuri if else.<\/p>\n<p><b>Configur\u0103ri<\/b> \u2014 aceasta este singura diferen\u021b\u0103 \u00eentre desf\u0103\u0219ur\u0103rile proiectului (deployment). Ideal, configura\u021biile ar trebui s\u0103 fie transmise prin variabile de mediu (env vars). <\/p>\n<p>Adic\u0103, chiar dac\u0103 ve\u021bi p\u0103stra mai multe fi\u0219iere de configurare .config.prod .config.local \u0219i le ve\u021bi redenumi \u00een momentul desf\u0103\u0219ur\u0103rii \u00een .config (configura\u021bia principal\u0103 din care aplica\u021bia cite\u0219te datele) \u2014 aceasta nu va fi o abordare corect\u0103, deoarece, \u00een acest caz, informa\u021biile din configura\u021bii vor fi accesibile tuturor dezvoltatorilor aplica\u021biei \u0219i datele de pe serverul de produc\u021bie vor fi compromise. Toate configura\u021biile trebuie s\u0103 fie stocate direct \u00een sistemul de desf\u0103\u0219urare (CI\/CD) \u0219i generate pentru diferite medii cu valori diferite necesare pentru fiecare mediu exact \u00een momentul desf\u0103\u0219ur\u0103rii.<\/p>\n<h4>4. Servicii externe (Backing Services)<\/h4>\n<p>\nLegat str\u00e2ns de mediu, folosi\u021bi conexiuni diferite pentru acelea\u0219i servicii \u00een medii specifice.<\/p>\n<p>Acest punct se suprapune foarte mult cu punctul despre configura\u021bii, deoarece f\u0103r\u0103 aceast\u0103 cerin\u021b\u0103 nu se pot crea date de configurare corespunz\u0103toare, iar posibilitatea de configurare va disp\u0103rea complet.<\/p>\n<p>Toate conexiunile la servicii externe, cum ar fi servere de mesaje, baze de date, servicii de cache, trebuie s\u0103 fie identice at\u00e2t pentru mediu local, c\u00e2t \u0219i pentru mediu extern \/ de produc\u021bie. Cu alte cuvinte, \u00een orice moment, pot schimba linia de conexiune \u00eenlocuind apelurile la baza de date #1 cu baza de date #2 f\u0103r\u0103 a modifica codul aplica\u021biei. Sau, pentru a anticipa, ca exemplu, la scalarea serviciului, nu va trebui s\u0103 specifica\u021bi o conexiune special\u0103 pentru un server de cache suplimentar.<\/p>\n<h4>5. Construire, lansare, execu\u021bie<\/h4>\n<p>\nAve\u021bi pe server doar versiunea final\u0103 a codului, f\u0103r\u0103 \u0219anse de a reveni la o versiune anterioar\u0103. Nu este nevoie s\u0103 ocupa\u021bi spa\u021biu pe disc. Cine crede c\u0103 poate lansa un cod pe produc\u021bie cu o eroare este un programator slab!<\/p>\n<p>Toate etapele desf\u0103\u0219ur\u0103rii trebuie s\u0103 fie separate \u00eentre ele.<\/p>\n<p>Ave\u021bi op\u021biunea de a reveni \u00eenapoi. Face\u021bi lans\u0103ri p\u0103str\u00e2nd \u00een acces rapid copii vechi ale aplica\u021biei (deja construite \u0219i preg\u0103tite pentru utilizare), astfel \u00eenc\u00e2t, \u00een cazul erorilor, s\u0103 pute\u021bi restabili versiunea anterioar\u0103. A\u0219a c\u0103, ipotetic, exist\u0103 un folder <i>releases<\/i> \u0219i un folder <i>current<\/i>, \u0219i dup\u0103 desf\u0103\u0219urarea \u0219i construc\u021bia reu\u0219it\u0103, folderul <i>current<\/i> este legat printr-un link simbolic de noua lansare care se afl\u0103 \u00een interior <i>releases<\/i> cu un nume asociat num\u0103rului de lansare. <\/p>\n<p>Aici ne amintim de Blue-Green deployment, care permite nu doar comutarea \u00eentre cod, ci \u0219i \u00eentre toate resursele \u0219i chiar medii, cu posibilitatea de a reveni asupra tuturor schimb\u0103rilor.<\/p>\n<h4>6. Procese<\/h4>\n<p>\nP\u0103stra\u021bi datele st\u0103rilor aplica\u021biei direct \u00een aplica\u021bie. Utiliza\u021bi sesiuni \u00een memoria opera\u021bional\u0103 a aplica\u021biei. Folosi\u021bi c\u00e2t mai multe resurse partajate \u00eentre serviciile externe. Asigura\u021bi-v\u0103 c\u0103 aplica\u021bia poate avea un singur proces \u0219i nu permite\u021bi scalarea.<\/p>\n<p>\u00cen leg\u0103tur\u0103 cu sesiunile, p\u0103stra\u021bi datele doar \u00een cache-ul controlat de serviciile externe (memcached, redis), astfel \u00eenc\u00e2t, chiar dac\u0103 ave\u021bi 20 de procese ale aplica\u021biei \u00een execu\u021bie, orice proces care acceseaz\u0103 cache-ul va putea continua s\u0103 lucreze cu clientul \u00een aceea\u0219i stare \u00een care utilizatorul a fost c\u00e2nd a interac\u021bionat cu aplica\u021bia din alt proces. Cu aceast\u0103 abordare, indiferent c\u00e2te copii ale serviciilor externe utiliza\u021bi, totul va func\u021biona corespunz\u0103tor \u0219i f\u0103r\u0103 probleme \u00een accesarea datelor.<\/p>\n<h4>7. Legarea porturilor (Port binding)<\/h4>\n<p>\nNumai serverul web trebuie s\u0103 \u0219tie cum s\u0103 lucreze cu serviciile externe. Sau ar fi mai bine s\u0103 ridica\u021bi serviciile externe direct \u00een serverul web. De exemplu, ca modul PHP \u00een Apache.<br \/>\nToate serviciile dumneavoastr\u0103 trebuie s\u0103 fie accessible unul altuia printr-o adres\u0103 \u0219i un port (localhost:5432, localhost:3000, nginx:80, php-fpm:9000), astfel, din nginx pot accesa at\u00e2t php-fpm, c\u00e2t \u0219i postgres, iar din php-fpm pot accesa postgres \u0219i nginx, iar din fiecare serviciu pot accesa alt serviciu. Astfel, viabilitatea unui serviciu nu depinde de viabilitatea altui serviciu.<\/p>\n<h4>8. Paralelism<\/h4>\n<p>\nLucra\u021bi cu un singur proces, altfel, mai multe procese s-ar putea s\u0103 nu func\u021bioneze bine \u00eempreun\u0103! <\/p>\n<p>L\u0103sa\u021bi posibilitatea de scalare. Docker Swarm este un instrument excelent pentru acest lucru. <br \/>\nDocker Swarm este un instrument pentru crearea \u0219i gestionarea clusterelor de containere at\u00e2t \u00eentre diferite ma\u0219ini, c\u00e2t \u0219i \u00eentre mai multe containere pe aceea\u0219i ma\u0219in\u0103.<\/p>\n<p>Folosind swarm, pot determina c\u00e2t de multe resurse voi aloca pentru fiecare proces \u0219i c\u00e2te procese din acela\u0219i serviciu voi lansa, iar echilibratorul intern, primind date pe un port prestabilit, va face automat proxy pentru procesele respective. Astfel, observ\u00e2nd c\u0103 \u00eenc\u0103rcarea pe server a crescut, pot ad\u0103uga mai multe procese, reduc\u00e2nd astfel \u00eenc\u0103rcarea pe anumite procese.<\/p>\n<h4>9. Utiilizabilitate (Disposability)<\/h4>\n<p>\nNu folosi\u021bi cozi pentru a lucra cu procese \u0219i date. Oprirea unui proces ar trebui s\u0103 influen\u021beze func\u021bionarea \u00eentregii aplica\u021bii. Dac\u0103 un serviciu se pr\u0103bu\u0219e\u0219te, toate se pr\u0103bu\u0219esc.<\/p>\n<p>Fiecare proces \u0219i serviciu pot fi oprite \u00een orice moment \u0219i acest lucru nu ar trebui s\u0103 afecteze celelalte servicii (aici nu m\u0103 refer la faptul c\u0103 un serviciu va deveni inaccesibil pentru alt serviciu, ci c\u0103 alt serviciu nu se va opri \u00een urma acestuia). Toate procesele trebuie s\u0103 se \u00eencheie \u00een mod suav, astfel \u00eenc\u00e2t, la finalizarea lor, datele s\u0103 nu fie afectate \u0219i la urm\u0103toarea pornire sistemul s\u0103 func\u021bioneze corect. Adic\u0103 chiar \u0219i \u00een cazul unei opriri accidentale, datele nu ar trebui s\u0103 fie afectate (aici se aplic\u0103 mecanismul tranzac\u021biilor, cererile \u00een bd func\u021bioneaz\u0103 doar \u00een grupuri, \u0219i dac\u0103 m\u0103car o cerere din grup nu a fost executat\u0103 sau a fost executat\u0103 cu eroare, atunci nici o alt\u0103 cerere din grup nu va fi, \u00een realitate, executat\u0103).<\/p>\n<h4>10. Paritatea dezvolt\u0103rii\/execu\u021biei aplica\u021biei<\/h4>\n<p>\nProdusul, stagingul \u0219i versiunea local\u0103 a aplica\u021biei trebuie s\u0103 fie diferite. Pe produc\u021bie avem frameworkul Yii Lite, iar local Yii, pentru a func\u021biona mai repede \u00een produc\u021bie!<\/p>\n<p>\u00cen realitate, toate desf\u0103\u0219ur\u0103rile \u0219i lucrul cu codul ar trebui s\u0103 se efectueze \u00eentr-un mediu aproape identic (nu este vorba despre hardware fizic). De asemenea, codul pe produc\u021bie ar trebui s\u0103 poat\u0103 fi desf\u0103\u0219urat, la nevoie, de orice membru al echipei de dezvoltare, nu doar de un departament devops specializat, care poate ridica aplica\u021bia \u00een produc\u021bie doar datorit\u0103 unei puteri speciale.<\/p>\n<p>Acest lucru ne ajut\u0103 \u0219i Docker. Respect\u00e2nd toate punctele anterioare, utilizarea Docker va reduce procesul de desf\u0103\u0219urare a mediului, at\u00e2t pe produc\u021bie, c\u00e2t \u0219i pe ma\u0219ina local\u0103, la introducerea a una sau dou\u0103 comenzi.<\/p>\n<h4>11. Jurnalizare (Logs)<\/h4>\n<p>\nScriem logurile \u00een fi\u0219iere \u0219i bd! Nu cur\u0103\u021b\u0103m fi\u0219iere \u0219i bd de loguri. Vom cump\u0103ra pur \u0219i simplu un hard disk de 9000 de petabyte \u0219i va fi bine.<\/p>\n<p>Toate logurile trebuie considerate ca un flux de evenimente. Aplica\u021bia \u00een sine nu ar trebui s\u0103 se ocupe cu procesarea logurilor. Logurile ar trebui fie s\u0103 fie emise \u00een stdout, fie s\u0103 fie trimise printr-un protocol precum udp, astfel \u00eenc\u00e2t munca aplica\u021biei cu logurile s\u0103 nu cauzeze nicio problem\u0103. Graylog este o alegere bun\u0103 pentru aceasta. Graylog, primind toate logurile prin udp (acest protocol nu necesit\u0103 a\u0219teptarea unui r\u0103spuns pentru confirmarea recep\u021biei pachetului) nu interfereaz\u0103 \u00een niciun fel cu aplica\u021bia \u0219i se ocup\u0103 doar de structurarea \u0219i procesarea logurilor. Logica aplica\u021biei nu se schimb\u0103 pentru a lucra cu astfel de abord\u0103ri.<\/p>\n<h4>12. Sarcini de administrare<\/h4>\n<p>\nPentru actualizarea datelor, a bazei de date etc., utiliza\u021bi un endpoint creat separat \u00een API, executarea acestuia de dou\u0103 ori consecutiv va duce la duplicarea tuturor datelor. Dar voi nu sunte\u021bi pro\u0219ti, nu ve\u021bi ap\u0103sa de dou\u0103 ori, iar migra\u021biile nu ne sunt necesare.<\/p>\n<p>Toate sarcinile de administrare trebuie executate \u00een aceea\u0219i mediu ca \u0219i tot codul, la nivelul versiunilor. A\u0219adar, dac\u0103 trebuie s\u0103 schimb\u0103m structura bazei de date, nu vom face acest lucru manual prin schimbarea numelui coloanelor \u0219i ad\u0103ugarea de noi coloane prin diferite instrumente vizuale de gestionare a bazei de date. Pentru asemenea lucruri cre\u0103m scripturi separate \u2013 migra\u021bii, care sunt executate oriunde \u0219i \u00een toate medii uniform, cu un rezultat comun \u0219i clar. Pentru toate celelalte sarcini, cum ar fi popularea proiectului cu date, trebuie aplicate metodologii similare.<\/p>\n<h3>Exemplu de implementare pe PHP, Laravel, Laradock, Docker-Compose<\/h3>\n<p>\nP.S. Toate exemplele au fost realizate pe MacOS. Cele mai multe se potrivesc \u0219i pentru Linux. Utilizatorilor de Windows, \u00eemi pare r\u0103u, dar nu am mai lucrat cu Windows de mult.<\/p>\n<p>S\u0103 presupunem c\u0103 pe PC-ul nostru nu este instalat\u0103 nicio versiune de PHP \u0219i de fapt nu avem nimic. <br \/>\nInstal\u0103m docker \u0219i docker-compose \u00een cele mai recente versiuni. (acest lucru poate fi g\u0103sit pe internet)<\/p>\n<pre><code class=\"bash\">docker -v &amp;&amp; \ndocker-compose -v\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/d9e77c47eef486befb6ebd8118403d13.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n1. Instal\u0103m <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=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/67b3214d9a5cff4596c4914ea6e199c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDespre Laradock pot spune c\u0103 este un lucru foarte grozav, \u00een care sunt adunate multe containere \u0219i instrumente auxiliare. Dar nu a\u0219 recomanda utilizarea Laradock a\u0219a cum este f\u0103r\u0103 modific\u0103ri \u00een produc\u021bie din cauza excesului s\u0103u. Este mai bine s\u0103 crea\u021bi propriile containere bazate pe exemplele din Laradock, astfel ve\u021bi avea multe op\u021biuni de optimizare, deoarece nim\u0103nui nu-i trebuie tot ce exist\u0103 acolo simultan.<\/p>\n<p>2. Configur\u0103m Laradock pentru a func\u021biona cu aplica\u021bia noastr\u0103.<\/p>\n<pre><code class=\"bash\">cd laradock &amp;&amp; \ncp env-example .env\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/df8107e1be933cc955be8ca5066f22f2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.1. Deschidem catalogul habr (folderul p\u0103rinte \u00een care a fost clonat laradock) \u00eentr-un editor. (\u00cen cazul meu, PHPStorm)<\/p>\n<p>\u00cen acest stadiu, set\u0103m doar numele proiectului.<\/p>\n<p><img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/f6026fd04130590539e0945db30ec0dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.2. Pornim imaginea workspace. (\u00cen cazul vostru, imaginile vor fi construite pentru o vreme)<br \/>\nWorkspace-ul este o imagine special preg\u0103tit\u0103 pentru a lucra cu framework-ul din perspectiva dezvoltatorului.<\/p>\n<p>Acces\u0103m \u00een interiorul containerului folosind <\/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=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/e839a5cd055b6c06c02cdd03a5054477.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.3. Instal\u0103m Laravel<\/p>\n<pre><code class=\"bash\">composer create-project --prefer-dist laravel\/laravel application<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/b21b3fc30ce1bec63aee43ab5fce53e3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.4. Dup\u0103 instalare, verific\u0103m dac\u0103 a fost creat\u0103 directorul cu proiectul \u0219i oprim compose.<\/p>\n<pre><code class=\"bash\">ls\nexit\ndocker-compose down\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/e812f383138637656ec96804833cfc53.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.5. Ne \u00eentoarcem \u00een PHPStorm \u0219i set\u0103m calea corect\u0103 c\u0103tre aplica\u021bia noastr\u0103 Laravel \u00een fi\u0219ierul .env.<\/p>\n<p><img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/abb9a5694d01163960af5375767f331b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n3. Ad\u0103ug\u0103m tot codul \u00een Git.<\/p>\n<p>Pentru aceasta, vom crea un repository pe Github (sau altundeva). Acces\u0103m terminalul \u00een directorul habr \u0219i execut\u0103m urm\u0103torul cod.<\/p>\n<pre><code class=\"bash\">echo &quot;# habr-12factor&quot; &gt;&gt; README.md\ngit init\ngit add README.md\ngit commit -m &quot;first commit&quot;\ngit remote add origin git@github.com:nzulfigarov\/habr-12factor.git # aici va fi linkul c\u0103tre depozitul vostru\ngit push -u origin master\ngit status\n<\/code><\/pre>\n<p>\nVerific\u0103m dac\u0103 totul este \u00een regul\u0103. <\/p>\n<p><img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/cbcb770a95d91655bdaf727be79742ab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPentru confort, recomand s\u0103 folosi\u021bi o oarecare interfa\u021b\u0103 vizual\u0103 pentru Git, \u00een cazul meu aceasta este <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gitkraken.com\/invite\/qXBXV9Wm\">GitKraken<\/a><\/noindex>. (aici este un link de referral)<\/p>\n<p>4. Pornim!<\/p>\n<p>\u00cenainte de a porni, asigura\u021bi-v\u0103 c\u0103 nu ave\u021bi nimic pe porturile 80 \u0219i 443.<\/p>\n<pre><code class=\"bash\">docker-compose up -d nginx php-fpm<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/f0bf0416e67b918e0966100e37c74454.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAstfel, proiectul nostru const\u0103 \u00een 3 servicii separate:<\/p>\n<ul>\n<li>nginx \u2014 server web<\/li>\n<li>php-fpm \u2014 php pentru preluarea cererilor de la serverul web<\/li>\n<li>workspace \u2014 php pentru dezvoltator<\/li>\n<\/ul>\n<p>\nP\u00e2n\u0103 \u00een acest moment, am reu\u0219it s\u0103 cre\u0103m o aplica\u021bie care corespunde deja la 4 puncte din 12, \u0219i anume:<\/p>\n<p>1. <b>Baza de cod<\/b> \u2014 tot codul se afl\u0103 \u00eentr-un singur repository (o mic\u0103 observa\u021bie: ar putea fi mai corect s\u0103 integr\u0103m docker \u00een proiectul Laravel, dar nu este esen\u021bial).<\/p>\n<p>2. <b>Dependin\u021be<\/b> \u2014 Toate dependen\u021bele noastre sunt clar specificate \u00een application\/composer.json \u0219i \u00een fiecare Dockerfile al fiec\u0103rui container.<\/p>\n<p>3. <b>Servicii externe (Backing Services)<\/b> \u2014 Fiecare dintre servicii (php-fpm, nginx, workspace) tr\u0103ie\u0219te via\u021ba sa \u0219i este conectat\u0103 din exterior, iar atunci c\u00e2nd lucr\u0103m cu un serviciu, celelalte nu vor fi afectate.<\/p>\n<p>4. <b>Procese<\/b> \u2014 fiecare serviciu reprezint\u0103 un proces. Fiecare dintre servicii nu \u00ee\u0219i p\u0103streaz\u0103 starea intern\u0103.<\/p>\n<p>5.<b> Legarea de porturi (Port binding)<\/b><\/p>\n<pre><code class=\"bash\">docker ps\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/e6e3fa4a12a43d1bcd51992c424c1245.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDup\u0103 cum vedem, fiecare serviciu este pornit pe propriul s\u0103u port \u0219i este disponibil pentru toate celelalte servicii.<\/p>\n<p>6.<b> Paralelism <\/b><\/p>\n<p>Docker ne permite s\u0103 ridic\u0103m mai multe procese ale acelora\u0219i servicii cu un balans automat al \u00eenc\u0103rc\u0103rii \u00eentre ele. <\/p>\n<p>Oprim containerele \u0219i le pornim cu ajutorul flag-ului <b>&#8212;scale<\/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=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/f5d279b8a034512dd20024272c7f03b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDup\u0103 cum vedem, containerul php-fpm a creat copii. Nu trebuie s\u0103 facem nimic \u00een lucrul cu acest container. De asemenea, continu\u0103m s\u0103 ne conect\u0103m la el pe portul 9000, iar Docker regleaz\u0103 sarcina \u00eentre containere.<\/p>\n<p>7. <b>Utilizabilitate (Disposability)<\/b> \u2014 fiecare container poate fi oprit f\u0103r\u0103 a afecta altul. Oprirea sau repornirea unui container nu va afecta func\u021bionarea aplica\u021biei la lans\u0103rile ulterioare. Fiecare container poate fi, de asemenea, ridicat oric\u00e2nd.<\/p>\n<p>8. <b>Paritatea dezvolt\u0103rii \/ rul\u0103rii aplica\u021biei<\/b> \u2014 toate mediile noastre sunt identice. Rul\u00e2nd sistemul pe server \u00een produc\u021bie, nu va trebui s\u0103 schimbi nimic \u00een comenzile tale. Totul va fi bazat exact pe Docker.<\/p>\n<p>9. <b>Jurnalizare (Logs)<\/b> \u2014 toate log-urile din aceste containere ies pe flux \u0219i sunt vizibile \u00een consola Docker. (\u00een acest caz, de fapt, cu alte containere personalizate, poate s\u0103 nu fie a\u0219a dac\u0103 nu te ocupi de asta)<\/p>\n<pre><code class=\"bash\"> docker-compose logs -f<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/67e275042b96f5270534466b426d4fdc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDar, aici este o problem\u0103, deoarece valorile implicite \u00een PHP \u0219i Nginx scriu de asemenea log-uri \u00een fi\u0219ier. Pentru a respecta cele 12 principii, este necesar <b>a dezactiva<\/b> scrierea log-urilor \u00een fi\u0219ier \u00een configura\u021biile fiec\u0103rui container separat.<\/p>\n<p>De asemenea, Docker ofer\u0103 posibilitatea de a direc\u021biona log-urile nu doar \u00een stdout, ci \u0219i \u00een lucruri precum graylog despre care am vorbit mai sus. Iar \u00een interiorul graylog, putem opera log-urile cum dorim \u0219i aplica\u021bia noastr\u0103 nu va observa asta.<\/p>\n<p>10. <b>Sarcini administrative<\/b> \u2014 toate sarcinile de administrare sunt rezolvate de Laravel prin instrumentul artisan exact a\u0219a cum \u0219i-ar dori creatorii aplica\u021biei de 12 factori.<\/p>\n<p>Ca exemplu, voi ar\u0103ta cum se execut\u0103 c\u00e2teva comenzi.<br \/>\nIntr\u0103m \u00een container.<\/p>\n<pre><code class=\"bash\"> \ndocker-compose exec workspace bash\nphp artisan list\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/3d5fb5bc40b4b8b0cb225116c0f3d625.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAcum putem folosi orice comand\u0103. (re\u021bine\u021bi c\u0103 nu am configurat baza de date \u0219i cache-ul, a\u0219a c\u0103 jum\u0103tate din comenzi nu se vor executa corect, deoarece sunt destinate lucrului cu cache-ul \u0219i baza de date).<\/p>\n<p><img decoding=\"async\" alt=\"Dezvoltarea aplica\u021biilor \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker\" src=\"\/wp-content\/uploads\/2020\/02\/6f84bb2ade2ade654d2c361c585edeae.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n11. <b>Configur\u0103ri<\/b> \u0219i 12. <b>Compilare, lansare, execu\u021bie<\/b><\/p>\n<p>Aceast\u0103 parte voiam s\u0103 o dedic Blue-Green Deployment, dar s-a dovedit prea extins\u0103 pentru acest articol. Voi scrie un articol separat despre asta. <\/p>\n<p>Pe scurt, conceptul se bazeaz\u0103 pe sistemele CI\/CD de tipul <b>Jenkins<\/b> \u0219i <b>Gitlab CI<\/b>. At\u00e2t \u00een unul, c\u00e2t \u0219i \u00een cel\u0103lalt, po\u021bi defini variabile de mediu legate de un mediu specific. Prin urmare, \u00een acest context, se va realiza punctul cu <b>Configura\u021biile<\/b>.<\/p>\n<p>Iar punctul despre <b>Compilare, lansare, execu\u021bie<\/b> se rezolv\u0103 prin func\u021biile \u00eencorporate \u00een ambele instrumente cu numele <b>Pipeline<\/b>.<\/p>\n<p><b>Pipeline<\/b> permite divizarea procesului de deploy \u00een mai multe etape, eviden\u021biind etapele de construire, lansare \u0219i execu\u021bie. De asemenea, \u00een Pipeline, ve\u021bi putea crea backup-uri \u0219i, \u00een general, orice dori\u021bi. Acest instrument are un poten\u021bial nelimitat.<\/p>\n<p>Codul aplica\u021biei se afl\u0103 pe <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nzulfigarov\/habr-12factor\">Github<\/a><\/noindex>.<br \/>\nNu uita\u021bi s\u0103 ini\u021bializa\u021bi submodulele la clonarea acestui repository.<\/p>\n<p>P.S.: Toate aceste metode pot fi folosite cu orice alte utilitare \u0219i limbaje de programare. Important e ca esen\u021ba s\u0103 nu se schimbe.<br \/>\n<br \/>Sursa: <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.2.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\/ro\/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.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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\udd47Dezvoltarea de aplica\u021bii \u0219i Blue-Green deployment, baz\u00e2ndu-se pe metodologia The Twelve-Factor App cu exemple \u00een php \u0219i docker | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/ro\/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":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/40596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=40596"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/40596\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/40597"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=40596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=40596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=40596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}