{"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\/pt\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","title":{"rendered":"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/c8f98efef30babe012d23dd82a01c13b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Para come\u00e7ar, um pouco de teoria. O que \u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">The Twelve-Factor App<\/a><\/noindex>?<\/h3>\n<p>\nEm termos simples, \u00e9 um documento que visa simplificar o desenvolvimento de aplicativos SaaS, ajudando os desenvolvedores e engenheiros de DevOps a entender os problemas e as pr\u00e1ticas que mais comumente surgem no desenvolvimento de aplicativos modernos. <\/p>\n<p>O documento foi elaborado pelos desenvolvedores da plataforma Heroku.<\/p>\n<p>A metodologia de doze fatores (The Twelve-Factor App) pode ser aplicada a aplicativos escritos em qualquer linguagem de programa\u00e7\u00e3o e que utilizam quaisquer combina\u00e7\u00f5es de servi\u00e7os externos (backing services) (bancos de dados, filas de mensagens, cache, etc.).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Resumidamente, aqui est\u00e3o os fatores que sustentam essa metodologia:<\/h3>\n<p><\/p>\n<ol>\n<li><b>Base de c\u00f3digo<\/b> \u2013 Uma base de c\u00f3digo, rastreada em um sistema de controle de vers\u00e3o, \u2013 m\u00faltiplas implanta\u00e7\u00f5es <\/li>\n<li><b>Depend\u00eancias<\/b> \u2013 Declare e isole depend\u00eancias explicitamente<\/li>\n<li><b>Configura\u00e7\u00e3o<\/b> \u2013 Mantenha a configura\u00e7\u00e3o no ambiente de execu\u00e7\u00e3o<\/li>\n<li><b>Servi\u00e7os externos (Backing Services)<\/b> \u2013 Considere servi\u00e7os externos (backing services) como recursos conect\u00e1veis<\/li>\n<li><b>Constru\u00e7\u00e3o, lan\u00e7amento, execu\u00e7\u00e3o<\/b> \u2013 Separe rigorosamente as etapas de constru\u00e7\u00e3o e execu\u00e7\u00e3o<\/li>\n<li><b>Processos<\/b> \u2013 Execute o aplicativo como um ou mais processos sem estado (stateless) <\/li>\n<li><b>Vincula\u00e7\u00e3o de portas (Port binding)<\/b> \u2013 Exporte servi\u00e7os por meio da vincula\u00e7\u00e3o de portas <\/li>\n<li><b>Paralelismo<\/b> \u2013 Escalone o aplicativo usando processos <\/li>\n<li><b>Descartabilidade (Disposability)<\/b> \u2013 Maximize a confiabilidade com inicializa\u00e7\u00e3o r\u00e1pida e encerramento ordenado <\/li>\n<li><b>Paridade de desenvolvimento\/produ\u00e7\u00e3o do aplicativo<\/b> \u2013 Mantenha os ambientes de desenvolvimento, de staging e de produ\u00e7\u00e3o o mais semelhantes poss\u00edvel <\/li>\n<li><b>Registro (Logs)<\/b> \u2013 Considere o log como um fluxo de eventos<\/li>\n<li><b>Tarefas administrativas<\/b> \u2013 Execute tarefas de administra\u00e7\u00e3o\/gerenciamento usando processos \u00fanicos <\/li>\n<\/ol>\n<p>\n<b>Mais informa\u00e7\u00f5es sobre os 12 fatores podem ser obtidas a partir dos seguintes recursos:<\/b><\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">Fonte prim\u00e1ria oficial<\/a><\/noindex> \u2014 leitura obrigat\u00f3ria<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/258739\/\">Artigo no habr. O aplicativo de doze fatores \u2014 The Twelve-Factor App<\/a><\/noindex> \u2014 tradu\u00e7\u00e3o oficial<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460363\/\">Artigo no habr. 7 fatores ausentes na abordagem 12 Factor App<\/a><\/noindex> \u2014 uma nova perspectiva sobre os 12 fatores com o objetivo de aprimor\u00e1-los.<\/li>\n<\/ul>\n<p><\/p>\n<h3>O que \u00e9 Blue-Green deployment?<\/h3>\n<p>\nBlue-Green deployment \u00e9 uma forma de entrega de aplicativo. <b>production<\/b> dessa forma, o cliente final n\u00e3o percebe nenhuma altera\u00e7\u00e3o do seu lado. Em outras palavras, a implanta\u00e7\u00e3o do aplicativo ocorre com zero <b>downtime<\/b>.<\/p>\n<p>O esquema cl\u00e1ssico do BG Deploy \u00e9 como mostrado na imagem abaixo. <\/p>\n<p><img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/8252356ac93ce40b248ab27982754985.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>No in\u00edcio, h\u00e1 2 servidores f\u00edsicos com o mesmo c\u00f3digo, aplicativo, projeto, e h\u00e1 um roteador (balanceador). <\/li>\n<li>O roteador inicialmente direciona todas as solicita\u00e7\u00f5es para um dos servidores (<b>alfa<\/b>). <\/li>\n<li>No momento em que \u00e9 necess\u00e1rio lan\u00e7ar novamente, todo o projeto \u00e9 atualizado em outro servidor (<b>azul<\/b>), que no momento n\u00e3o est\u00e1 processando nenhuma solicita\u00e7\u00e3o. <\/li>\n<li>Depois que o c\u00f3digo no <b>servidor azul<\/b> estiver completamente atualizado, o roteador recebe a ordem de mudar do <b>servidor verde<\/b> para <b>azul<\/b> servidor. <\/li>\n<li>Agora todos os clientes veem o resultado do trabalho do c\u00f3digo no <b>servidor azul<\/b> servidor f\u00edsico. <\/li>\n<li> Por um tempo, <b>alfa<\/b> o servidor serve como backup caso a implanta\u00e7\u00e3o no <b>azul<\/b> servidor falhe e, em caso de falha e bugs, o roteador redireciona o fluxo de usu\u00e1rios de volta para o <b>alfa<\/b> servidor com a vers\u00e3o est\u00e1vel antiga, enquanto o novo c\u00f3digo \u00e9 enviado para melhorias e testes.<\/li>\n<li>E no final do processo, o <b>alfa<\/b> servidor tamb\u00e9m \u00e9 atualizado. E ap\u00f3s sua atualiza\u00e7\u00e3o, o roteador redireciona o fluxo de solicita\u00e7\u00f5es de volta para <b>alfa<\/b> servidor.<\/li>\n<\/ul>\n<p>\nIsso tudo parece muito bom e, \u00e0 primeira vista, n\u00e3o deve haver problemas com isso.<br \/>\nMas como vivemos em um mundo moderno, a op\u00e7\u00e3o de troca f\u00edsica, como indicado no esquema cl\u00e1ssico, n\u00e3o \u00e9 adequada para n\u00f3s. Por enquanto, registre essas informa\u00e7\u00f5es, retornaremos a elas mais tarde.<\/p>\n<h3>Conselhos bons e ruins<\/h3>\n<p>\n<i>Aviso Legal<\/i>: Nos exemplos abaixo est\u00e3o utilit\u00e1rios \/ metodologias que eu uso, voc\u00ea pode utilizar absolutamente quaisquer alternativas com fun\u00e7\u00f5es semelhantes. <\/p>\n<p>A maior parte dos exemplos ir\u00e1, de alguma forma, se sobrepor ao desenvolvimento web (surpresa, n\u00e3o \u00e9?), ao PHP e ao Docker.<\/p>\n<p>Nos pontos abaixo, h\u00e1 uma descri\u00e7\u00e3o pr\u00e1tica simples do uso de fatores em exemplos espec\u00edficos; se voc\u00ea deseja obter mais teoria sobre o assunto, consulte as refer\u00eancias acima ao material original. <\/p>\n<h4>1. C\u00f3digo fonte<\/h4>\n<p>\nUse FTP e FileZilla para carregar arquivos nos servidores um a um, n\u00e3o armazene o c\u00f3digo em nenhum lugar al\u00e9m do servidor de produ\u00e7\u00e3o.<\/p>\n<p>O projeto deve sempre ter uma \u00fanica base de c\u00f3digo, ou seja, todo o c\u00f3digo vem de uma s\u00f3 fonte. <b>Git<\/b> reposit\u00f3rios. Os servidores (produ\u00e7\u00e3o, staging, teste1, teste2 ...) utilizam o c\u00f3digo de ramos de um reposit\u00f3rio comum. Assim, garantimos a consist\u00eancia do c\u00f3digo.<\/p>\n<h4>2. Depend\u00eancias<\/h4>\n<p>\nBaixe todas as bibliotecas em pastas diretamente na raiz do projeto. As atualiza\u00e7\u00f5es devem ser feitas simplesmente transferindo o novo c\u00f3digo para a pasta com a vers\u00e3o atual da biblioteca. Instale todas as utilidades diretamente no servidor de hospedagem onde operam mais 20 servi\u00e7os.<\/p>\n<p>Um projeto deve sempre ter uma lista de depend\u00eancias claramente definida (entendo por depend\u00eancias tamb\u00e9m o ambiente). Todas as depend\u00eancias devem ser explicitamente definidas e isoladas. <br \/>\nComo exemplo, vamos considerar <b>Composer<\/b> e <b>Docker<\/b>.<\/p>\n<p><b>Composer<\/b> \u2014 um gerenciador de pacotes que permite instalar bibliotecas PHP. O Composer possibilita especificar vers\u00f5es de forma rigorosa ou n\u00e3o, e defini-las claramente. No servidor, podem existir 20 projetos diferentes, cada um com sua pr\u00f3pria lista de pacotes e bibliotecas, sem depender uns dos outros.<\/p>\n<p><b>Docker<\/b> \u2014 uma ferramenta que permite definir e isolar o ambiente em que o aplicativo ir\u00e1 operar. Consequentemente, assim como acontece com o Composer, mas de uma forma mais robusta, podemos definir com o que o aplicativo trabalha. Escolha uma vers\u00e3o espec\u00edfica do PHP, instale apenas os pacotes necess\u00e1rios para o funcionamento do projeto, sem adicionar nada desnecess\u00e1rio. E o mais importante, sem interferir nos pacotes e no ambiente do servidor de hospedagem e de outros projetos. Assim, todos os projetos no servidor que operam atrav\u00e9s do Docker podem utilizar qualquer conjunto de pacotes e ambientes completamente diferentes.<\/p>\n<h4>3. Configura\u00e7\u00e3o<\/h4>\n<p>\nArmazene as configura\u00e7\u00f5es como constantes diretamente no c\u00f3digo. Constantes distintas para o servidor de teste e para o ambiente de produ\u00e7\u00e3o. Conecte o funcionamento do aplicativo \u00e0s depend\u00eancias do ambiente diretamente na l\u00f3gica de neg\u00f3cios do projeto, utilizando estruturas if else.<\/p>\n<p><b>Configura\u00e7\u00f5es<\/b> \u2014 \u00e9 a \u00fanica coisa que deve diferenciar as implanta\u00e7\u00f5es do projeto. Idealmente, as configura\u00e7\u00f5es devem ser transmitidas atrav\u00e9s de vari\u00e1veis de ambiente (env vars). <\/p>\n<p>Ou seja, mesmo que voc\u00ea armazene v\u00e1rios arquivos de configura\u00e7\u00e3o .config.prod e .config.local e os renomeie no momento da implanta\u00e7\u00e3o para .config (configura\u00e7\u00e3o principal de onde o aplicativo l\u00ea os dados) \u2014 isso n\u00e3o ser\u00e1 uma abordagem correta, pois, dessa forma, as informa\u00e7\u00f5es das configura\u00e7\u00f5es estar\u00e3o acess\u00edveis a todos os desenvolvedores do aplicativo e os dados do servidor de produ\u00e7\u00e3o estar\u00e3o comprometidos. Todas as configura\u00e7\u00f5es devem ser armazenadas diretamente no sistema de implanta\u00e7\u00e3o (CI\/CD) e geradas para diferentes ambientes com valores distintos necess\u00e1rios para cada ambiente exatamente no momento da implanta\u00e7\u00e3o.<\/p>\n<h4>4. Servi\u00e7os de terceiros (Backing Services)<\/h4>\n<p>\nCrie uma forte depend\u00eancia do ambiente, utilizando diferentes conex\u00f5es para os mesmos servi\u00e7os em determinados ambientes.<\/p>\n<p>Na verdade, este ponto est\u00e1 intimamente relacionado ao ponto sobre configura\u00e7\u00f5es, pois sem a presen\u00e7a deste item n\u00e3o ser\u00e1 poss\u00edvel ter dados de configura\u00e7\u00e3o adequados e, de fato, a capacidade de configura\u00e7\u00e3o se tornar\u00e1 obsoleta.<\/p>\n<p>Todas as conex\u00f5es com servi\u00e7os externos, como servidores de filas, bancos de dados e servi\u00e7os de cache, devem ser consistentes tanto para o ambiente local quanto para o externo \/ ambiente de produ\u00e7\u00e3o. Em outras palavras, a qualquer momento, eu posso mudar a string de conex\u00e3o e substituir as chamadas ao banco #1 pelo banco #2 sem alterar o c\u00f3digo do aplicativo. Ou, antecipando um exemplo, ao escalar o servi\u00e7o, voc\u00ea n\u00e3o precisar\u00e1 indicar a conex\u00e3o de uma maneira especial para um novo servidor de cache.<\/p>\n<h4>5. Constru\u00e7\u00e3o, lan\u00e7amento, execu\u00e7\u00e3o<\/h4>\n<p>\nTenha apenas a vers\u00e3o final do c\u00f3digo no servidor, sem chances de reverter o lan\u00e7amento. N\u00e3o \u00e9 necess\u00e1rio consumir espa\u00e7o em disco. Quem acha que pode lan\u00e7ar c\u00f3digo em produ\u00e7\u00e3o com erro \u00e9 um mau programador!<\/p>\n<p>Todas as etapas de implanta\u00e7\u00e3o devem ser separadas entre si.<\/p>\n<p>Tenha a possibilidade de reverter. Fa\u00e7a lan\u00e7amentos mantendo c\u00f3pias antigas do aplicativo (j\u00e1 compiladas e prontas para uso) em acesso r\u00e1pido, para que, em caso de erros, seja poss\u00edvel restaurar a vers\u00e3o anterior. Ou seja, existe uma pasta <i>releases<\/i> e uma pasta <i>corrente<\/i>, e ap\u00f3s uma implanta\u00e7\u00e3o e compila\u00e7\u00e3o bem-sucedidas, a pasta <i>corrente<\/i> \u00e9 vinculada por um link simb\u00f3lico ao novo lan\u00e7amento que est\u00e1 dentro <i>releases<\/i> com um nome correspondente ao n\u00famero do lan\u00e7amento. <\/p>\n<p>Aqui lembramos do Blue-Green deployment, que permite n\u00e3o apenas alternar entre c\u00f3digos, mas tamb\u00e9m entre todos os recursos e at\u00e9 ambientes, com a capacidade de reverter tudo.<\/p>\n<h4>6. Processos<\/h4>\n<p>\nArmazene os dados de estado do aplicativo diretamente no pr\u00f3prio aplicativo. Utilize sess\u00f5es na mem\u00f3ria do pr\u00f3prio aplicativo. Aproveite ao m\u00e1ximo o que pode ser compartilhado entre servi\u00e7os externos. Baseie-se no fato de que o aplicativo pode ter apenas um processo e n\u00e3o permita a possibilidade de escalonamento.<\/p>\n<p>Em rela\u00e7\u00e3o \u00e0s sess\u00f5es, armazene os dados apenas em cache controlado por servi\u00e7os externos (memcached, redis). Assim, mesmo que voc\u00ea tenha 20 processos do aplicativo em execu\u00e7\u00e3o, qualquer um deles que acessar o cache poder\u00e1 continuar trabalhando com o cliente no mesmo estado em que o usu\u00e1rio estava ao interagir com o aplicativo em outro processo. Com essa abordagem, n\u00e3o importa quantas inst\u00e2ncias de servi\u00e7os externos voc\u00ea utilize, tudo funcionar\u00e1 normalmente e sem problemas de acesso aos dados.<\/p>\n<h4>7. Liga\u00e7\u00e3o de Portos (Port binding)<\/h4>\n<p>\nSomente o servidor web deve saber como trabalhar com servi\u00e7os externos. Melhor ainda, suba servi\u00e7os externos diretamente dentro do servidor web, como um m\u00f3dulo PHP no Apache.<br \/>\nTodos os seus servi\u00e7os devem ser acess\u00edveis entre si atrav\u00e9s de um endere\u00e7o e porta (localgost:5432, localhost:3000, nginx:80, php-fpm:9000). Assim, a partir do nginx eu posso acessar tanto o php-fpm quanto o postgres, e a partir do php-fpm eu posso acessar o postgres e o nginx. Dessa maneira, a viabilidade de um servi\u00e7o n\u00e3o depende da viabilidade de outro servi\u00e7o.<\/p>\n<h4>8. Paralelismo<\/h4>\n<p>\nTrabalhe com um \u00fanico processo, pois v\u00e1rios processos podem n\u00e3o conseguir se entender! <\/p>\n<p>Deixe a possibilidade de escalabilidade. O Docker Swarm \u00e9 uma \u00f3tima op\u00e7\u00e3o para isso. <br \/>\nDocker Swarm \u00e9 uma ferramenta para criar e gerenciar clusters de cont\u00eaineres, tanto entre diferentes m\u00e1quinas quanto um monte de cont\u00eaineres em uma \u00fanica m\u00e1quina.<\/p>\n<p>Usando swarm, posso determinar quanta capacidade vou alocar para cada processo e qual a quantidade de processos do mesmo servi\u00e7o que vou iniciar, e o balanceador interno, recebendo dados na porta designada, ir\u00e1 automaticamente proxy esses dados para os processos. Assim, ao notar que a carga no servidor aumentou, posso adicionar mais processos, reduzindo assim a carga em processos espec\u00edficos.<\/p>\n<h4>9. Descartabilidade (Disposability)<\/h4>\n<p>\nN\u00e3o use filas para trabalhar com processos e dados. A finaliza\u00e7\u00e3o de um processo deve impactar o funcionamento de toda a aplica\u00e7\u00e3o. Se um servi\u00e7o falhar, tudo falha.<\/p>\n<p>Cada processo e servi\u00e7o podem ser desligados a qualquer momento, e isso n\u00e3o deve afetar outros servi\u00e7os (n\u00e3o se referindo a que o servi\u00e7o ficar\u00e1 indispon\u00edvel para outro servi\u00e7o, mas sim que outro servi\u00e7o n\u00e3o ir\u00e1 desativar se seguir este). Todos os processos devem ser encerrados suavemente, de modo que ao finaliz\u00e1-los, os dados n\u00e3o sejam prejudicados, e ao lig\u00e1-los novamente, o sistema funcione corretamente. Em outras palavras, mesmo em caso de encerramento abrupto, os dados n\u00e3o devem ser danificados (um mecanismo de transa\u00e7\u00f5es \u00e9 adequado, onde as solicita\u00e7\u00f5es ao banco de dados funcionam apenas em grupos, e se uma solicita\u00e7\u00e3o do grupo falhar ou ocorrer um erro, nenhuma outra solicita\u00e7\u00e3o do grupo ser\u00e1 realmente executada).<\/p>\n<h4>10. Paridade entre Desenvolvimento e Opera\u00e7\u00e3o da Aplica\u00e7\u00e3o<\/h4>\n<p>\nAs vers\u00f5es de produ\u00e7\u00e3o, est\u00e1gio e local da aplica\u00e7\u00e3o devem ser diferentes. Em produ\u00e7\u00e3o, utilizamos o framework Yii Lite, enquanto localmente usamos o Yii, para que funcione mais r\u00e1pido em produ\u00e7\u00e3o!<\/p>\n<p>Na verdade, todos os desdobramentos e o trabalho com o c\u00f3digo devem ocorrer em ambientes praticamente id\u00eanticos (n\u00e3o me refiro ao hardware f\u00edsico). Al\u00e9m disso, a implementa\u00e7\u00e3o do c\u00f3digo em produ\u00e7\u00e3o deve ser realizada por qualquer membro da equipe de desenvolvimento, e n\u00e3o apenas por alguma equipe de devops especificamente treinada que, devido a alguma habilidade especial, pode iniciar a aplica\u00e7\u00e3o em produ\u00e7\u00e3o.<\/p>\n<p>Isso tamb\u00e9m \u00e9 facilitado pelo Docker. Com a ades\u00e3o a todos os pontos anteriores, o uso do docker tornar\u00e1 o processo de desdobramento em um ambiente tanto em produ\u00e7\u00e3o quanto em uma m\u00e1quina local em apenas um ou dois comandos.<\/p>\n<h4>11. Registro (Logs)<\/h4>\n<p>\nEscrevemos logs em arquivos e no banco de dados! N\u00e3o limpamos arquivos e bancos de dados de logs. Vamos simplesmente comprar um disco r\u00edgido de 9000 Petabytes e est\u00e1 bom.<\/p>\n<p>Todos os logs devem ser considerados como um fluxo de eventos. O pr\u00f3prio aplicativo n\u00e3o deve processar logs. Os logs devem ser enviados para stdout ou transmitidos por um protocolo como o UDP, para que o trabalho com logs n\u00e3o cause problemas para o aplicativo. Para isso, o graylog \u00e9 uma boa op\u00e7\u00e3o. Ao aceitar todos os logs via UDP (neste protocolo, n\u00e3o \u00e9 necess\u00e1rio esperar por uma confirma\u00e7\u00e3o de recebimento do pacote), o graylog n\u00e3o interfere de forma alguma no aplicativo e se ocupa apenas de estruturar e processar logs. A l\u00f3gica do aplicativo n\u00e3o muda para trabalhar com essas abordagens.<\/p>\n<h4>12. Tarefas de administra\u00e7\u00e3o<\/h4>\n<p>\nPara atualizar dados, banco de dados, etc., utilize um endpoint separado na API. A execu\u00e7\u00e3o deste dois vezes seguidas pode resultar em duplica\u00e7\u00e3o de dados. Mas voc\u00eas n\u00e3o s\u00e3o tolos, n\u00e3o clicariam duas vezes, e migra\u00e7\u00f5es n\u00e3o s\u00e3o necess\u00e1rias.<\/p>\n<p>Todas as tarefas de administra\u00e7\u00e3o devem ser realizadas no mesmo ambiente que todo o c\u00f3digo, ao n\u00edvel de releases. Ou seja, se precisamos alterar a estrutura do banco de dados, n\u00e3o o faremos manualmente mudando nomes de colunas e adicionando novas por meio de ferramentas visuais de gerenciamento de banco de dados. Para essas tarefas, criamos scripts separados \u2014 migra\u00e7\u00f5es, que s\u00e3o executadas em todos os ambientes de forma consistente e com resultados claros. Para todas as outras tarefas, como preencher o projeto com dados, devem ser aplicadas metodologias semelhantes.<\/p>\n<h3>Exemplo de implementa\u00e7\u00e3o em PHP, Laravel, Laradock, Docker-Compose<\/h3>\n<p>\nP.S. Todos os exemplos foram feitos no MacOS. A maior parte servir\u00e1 tamb\u00e9m para Linux. Usu\u00e1rios Windows, pe\u00e7o desculpas, mas n\u00e3o trabalho com Windows h\u00e1 muito tempo.<\/p>\n<p>Vamos imaginar uma situa\u00e7\u00e3o em que nenhuma vers\u00e3o do PHP est\u00e1 instalada no PC e na verdade nada est\u00e1 instalado. <br \/>\nInstalamos as vers\u00f5es mais recentes do Docker e do Docker Compose. (isso pode ser encontrado na internet)<\/p>\n<pre><code class=\"bash\">docker -v &amp;&amp; \ndocker-compose -v\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/d9e77c47eef486befb6ebd8118403d13.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n1. Instalamos <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=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/67b3214d9a5cff4596c4914ea6e199c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSobre o Laradock, posso dizer que \u00e9 uma ferramenta muito \u00fatil, que re\u00fane muitos cont\u00eaineres e utilit\u00e1rios. Mas usar o Laradock como est\u00e1 em produ\u00e7\u00e3o \u2014 eu n\u00e3o recomendaria devido \u00e0 sua complexidade. \u00c9 melhor criar seus pr\u00f3prios cont\u00eaineres com base nos exemplos do Laradock, assim haver\u00e1 espa\u00e7o para otimiza\u00e7\u00e3o, pois ningu\u00e9m precisa de tudo o que existe l\u00e1 ao mesmo tempo.<\/p>\n<p>2. Configuramos o Laradock para o funcionamento do nosso aplicativo.<\/p>\n<pre><code class=\"bash\">cd laradock &amp;&amp; \ncp env-example .env\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/df8107e1be933cc955be8ca5066f22f2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.1. Abra o diret\u00f3rio habr (a pasta pai onde o laradock foi clonado) em qualquer editor. (No meu caso, PHPStorm)<\/p>\n<p>Nesta etapa, vamos apenas dar um nome ao projeto.<\/p>\n<p><img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/f6026fd04130590539e0945db30ec0dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.2. Iniciamos a imagem workspace. (No seu caso, as imagens levar\u00e3o algum tempo para serem constru\u00eddas)<br \/>\nWorkspace \u00e9 uma imagem especialmente preparada para trabalhar com o framework em nome do desenvolvedor.<\/p>\n<p>Vamos dentro do cont\u00eainer usando <\/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=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/e839a5cd055b6c06c02cdd03a5054477.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.3. Instalamos o Laravel<\/p>\n<pre><code class=\"bash\">composer create-project --prefer-dist laravel\/laravel application<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/b21b3fc30ce1bec63aee43ab5fce53e3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.4. Depois da instala\u00e7\u00e3o, verificamos se a diret\u00f3rio do projeto foi criada e encerramos o compose.<\/p>\n<pre><code class=\"bash\">ls\nexit\ndocker-compose down\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/e812f383138637656ec96804833cfc53.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.5. Voltamos para o PHPStorm e definimos o caminho correto para nossa aplica\u00e7\u00e3o Laravel no arquivo .env.<\/p>\n<p><img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/abb9a5694d01163960af5375767f331b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n3. Adicionamos todo o c\u00f3digo ao Git.<\/p>\n<p>Para isso, vamos criar um reposit\u00f3rio no Github (ou em qualquer outro lugar). Vamos para a pasta habr no terminal e executamos o seguinte c\u00f3digo.<\/p>\n<pre><code class=\"bash\">echo \"# habr-12factor\" &gt;&gt; README.md\ngit init\ngit add README.md\ngit commit -m \"primeiro commit\"\ngit remote add origin git@github.com:nzulfigarov\/habr-12factor.git # aqui estar\u00e1 o link para seu reposit\u00f3rio\ngit push -u origin master\ngit status\n<\/code><\/pre>\n<p>\nVerificamos se tudo est\u00e1 em ordem. <\/p>\n<p><img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/cbcb770a95d91655bdaf727be79742ab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPara conveni\u00eancia, recomendo usar alguma interface visual para Git, no meu caso \u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gitkraken.com\/invite\/qXBXV9Wm\">GitKraken<\/a><\/noindex>. (aqui est\u00e1 o link de refer\u00eancia)<\/p>\n<p>4. Vamos come\u00e7ar!<\/p>\n<p>Antes de iniciar, assegure-se de que nada est\u00e1 rodando nas portas 80 e 443.<\/p>\n<pre><code class=\"bash\">docker-compose up -d nginx php-fpm<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/f0bf0416e67b918e0966100e37c74454.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAssim, nosso projeto consiste em 3 servi\u00e7os separados:<\/p>\n<ul>\n<li>nginx \u2014 servidor web<\/li>\n<li>php-fpm \u2014 PHP para receber solicita\u00e7\u00f5es do servidor web<\/li>\n<li>workspace \u2014 PHP para desenvolvedor<\/li>\n<\/ul>\n<p>\nAt\u00e9 o momento, conseguimos criar uma aplica\u00e7\u00e3o que atende a 4 dos 12 pontos, a saber:<\/p>\n<p>1. <b>Base de c\u00f3digo<\/b> \u2014 todo o c\u00f3digo est\u00e1 em um \u00fanico reposit\u00f3rio (uma pequena observa\u00e7\u00e3o: pode ser mais correto incorporar o docker dentro do projeto Laravel, mas isso n\u00e3o \u00e9 fundamental).<\/p>\n<p>2. <b>Depend\u00eancias<\/b> \u2014 Todas as nossas depend\u00eancias est\u00e3o claramente especificadas em application\/composer.json e em cada Dockerfile de cada cont\u00eainer.<\/p>\n<p>3. <b>Servi\u00e7os externos (Backing Services)<\/b> \u2014 Cada um dos servi\u00e7os (php-fpm, nginx, workspace) vive sua pr\u00f3pria vida e \u00e9 conectado externamente, ent\u00e3o ao trabalhar com um servi\u00e7o, o outro n\u00e3o ser\u00e1 afetado.<\/p>\n<p>4. <b>Processos<\/b> \u2014 cada servi\u00e7o \u00e9 um \u00fanico processo. Cada um dos servi\u00e7os n\u00e3o mant\u00e9m estado interno.<\/p>\n<p>5.<b> Vincula\u00e7\u00e3o de portas (Port binding)<\/b><\/p>\n<pre><code class=\"bash\">docker ps\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/e6e3fa4a12a43d1bcd51992c424c1245.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComo podemos ver, cada servi\u00e7o est\u00e1 rodando na sua pr\u00f3pria porta e acess\u00edvel a todos os outros servi\u00e7os.<\/p>\n<p>6.<b> Paralelismo <\/b><\/p>\n<p>O Docker nos permite iniciar v\u00e1rios processos dos mesmos servi\u00e7os com balanceamento autom\u00e1tico de carga entre eles. <\/p>\n<p>Vamos parar os cont\u00eaineres e inici\u00e1-los com a flag <b>\u2014escala<\/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=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/f5d279b8a034512dd20024272c7f03b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComo podemos ver, o cont\u00eainer php-fpm criou c\u00f3pias. N\u00e3o precisamos mudar nada neste cont\u00eainer. Continuamos acessando-o pela porta 9000, enquanto o Docker gerencia a carga entre os cont\u00eaineres.<\/p>\n<p>7. <b>Descartabilidade (Disposability)<\/b> \u2014 cada cont\u00eainer pode ser parado sem prejudicar outro. Parar ou reiniciar um cont\u00eainer n\u00e3o afetar\u00e1 a opera\u00e7\u00e3o do aplicativo em execu\u00e7\u00f5es futuras. Cada cont\u00eainer tamb\u00e9m pode ser levantado a qualquer momento.<\/p>\n<p>8. <b>Paridade de desenvolvimento\/produ\u00e7\u00e3o do aplicativo<\/b> \u2014 todos os nossos ambientes s\u00e3o id\u00eanticos. Ao iniciar o sistema em um servidor de produ\u00e7\u00e3o, voc\u00ea n\u00e3o precisar\u00e1 mudar nada em seus comandos. Tudo funcionar\u00e1 exatamente com base no Docker.<\/p>\n<p>9. <b>Registro (Logs)<\/b> \u2014 todos os logs desses cont\u00eaineres s\u00e3o direcionados para o fluxo e vis\u00edveis no console do Docker. (neste caso, na verdade, com outros cont\u00eaineres personalizados, pode n\u00e3o ser assim se voc\u00ea n\u00e3o cuidar disso)<\/p>\n<pre><code class=\"bash\"> docker-compose logs -f<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/67e275042b96f5270534466b426d4fdc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMas, aqui est\u00e1 a pegadinha: os valores padr\u00e3o em PHP e Nginx tamb\u00e9m gravam logs em arquivo. Para atender aos 12 fatores, \u00e9 necess\u00e1rio <b>desativar<\/b> a grava\u00e7\u00e3o de logs em arquivo nas configura\u00e7\u00f5es de cada cont\u00eainer separadamente.<\/p>\n<p>O Docker tamb\u00e9m oferece a possibilidade de direcionar logs n\u00e3o apenas para stdout, mas tamb\u00e9m para coisas como graylog, como eu mencionei acima. E dentro do graylog, podemos operar os logs como quisermos e nosso aplicativo n\u00e3o perceber\u00e1 isso.<\/p>\n<p>10. <b>Tarefas administrativas<\/b> \u2014 todas as tarefas administrativas s\u00e3o resolvidas pelo Laravel gra\u00e7as \u00e0 ferramenta artisan, exatamente como os criadores do 12 fatores desejariam.<\/p>\n<p>Como exemplo, vou mostrar como alguns comandos s\u00e3o executados.<br \/>\nEntramos no cont\u00eainer.<\/p>\n<pre><code class=\"bash\"> \ndocker-compose exec workspace bash\nphp artisan list\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/3d5fb5bc40b4b8b0cb225116c0f3d625.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAgora podemos usar qualquer comando. (note que n\u00e3o configuramos o banco de dados e o cache, portanto metade dos comandos n\u00e3o ser\u00e1 executada corretamente, pois est\u00e3o destinados ao trabalho com cache e bds).<\/p>\n<p><img decoding=\"async\" alt=\"Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker\" src=\"\/wp-content\/uploads\/2020\/02\/6f84bb2ade2ade654d2c361c585edeae.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n11. <b>Configura\u00e7\u00f5es<\/b> e 12. <b>Constru\u00e7\u00e3o, lan\u00e7amento, execu\u00e7\u00e3o<\/b><\/p>\n<p>Esta parte eu queria dedicar ao Blue-Green Deployment, mas isso se mostrou muito extenso para este artigo. Vou escrever um artigo separado sobre isso. <\/p>\n<p>Em poucas palavras, o conceito \u00e9 baseado em sistemas CI\/CD como <b>Jenkins<\/b> e <b>Gitlab CI<\/b>. Em ambos, voc\u00ea pode definir vari\u00e1veis de ambiente relacionadas a um ambiente espec\u00edfico. Assim, nessa configura\u00e7\u00e3o, o ponto sobre <b>Configura\u00e7\u00f5es<\/b>.<\/p>\n<p>E o ponto sobre <b>Constru\u00e7\u00e3o, lan\u00e7amento, execu\u00e7\u00e3o<\/b> \u00e9 resolvido por fun\u00e7\u00f5es integradas em ambas as ferramentas chamadas <b>Pipeline<\/b>.<\/p>\n<p><b>Pipeline<\/b> permite dividir o processo de implanta\u00e7\u00e3o em v\u00e1rias etapas, destacando as fases de constru\u00e7\u00e3o, lan\u00e7amento e execu\u00e7\u00e3o. No Pipeline, voc\u00ea tamb\u00e9m poder\u00e1 criar backups e fazer praticamente qualquer coisa. Esta ferramenta possui um potencial ilimitado.<\/p>\n<p>O c\u00f3digo do aplicativo est\u00e1 localizado em <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nzulfigarov\/habr-12factor\">Github<\/a><\/noindex>.<br \/>\nN\u00e3o se esque\u00e7a de inicializar o subm\u00f3dulo ao clonar este reposit\u00f3rio.<\/p>\n<p>P.S.: Todas essas abordagens podem ser usadas com quaisquer outras ferramentas e linguagens de programa\u00e7\u00e3o. O importante \u00e9 que a ess\u00eancia n\u00e3o mude.<br \/>\n<br \/>Fonte: <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.3 - 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\/pt\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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\udd47Desenvolvimento de aplicativos e Blue-Green deployment, baseado na metodologia The Twelve-Factor App com exemplos em php e docker | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/pt\/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":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/40596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=40596"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/40596\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/40597"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=40596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=40596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=40596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}