{"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\/es\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","title":{"rendered":"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/c8f98efef30babe012d23dd82a01c13b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Para comenzar, un poco de teor\u00eda. \u00bfQu\u00e9 es <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">La Aplicaci\u00f3n de Doce Factores<\/a><\/noindex>?<\/h3>\n<p>\nEn t\u00e9rminos simples, este documento est\u00e1 dise\u00f1ado para simplificar el desarrollo de aplicaciones SaaS, ayudando a informar a los desarrolladores e ingenieros de DevOps sobre los problemas y pr\u00e1cticas m\u00e1s comunes en el desarrollo de aplicaciones modernas. <\/p>\n<p>El documento fue creado por los desarrolladores de la plataforma Heroku.<\/p>\n<p>La metodolog\u00eda de doce factores (The Twelve-Factor App) puede aplicarse a aplicaciones escritas en cualquier lenguaje de programaci\u00f3n y que utilizan cualquier combinaci\u00f3n de servicios externos (backing services) (bases de datos, colas de mensajes, almacenamiento en cach\u00e9, etc.).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>En breve sobre los propios factores en los que se basa esta metodolog\u00eda:<\/h3>\n<p><\/p>\n<ol>\n<li><b>Base de c\u00f3digo<\/b> \u2013 Una base de c\u00f3digo, controlada por un sistema de control de versiones, \u2013 m\u00faltiples despliegues <\/li>\n<li><b>Dependencias<\/b> \u2013 Declare y a\u00edsle expl\u00edcitamente las dependencias<\/li>\n<li><b>Configuraci\u00f3n<\/b> \u2013 Almacene la configuraci\u00f3n en el entorno de ejecuci\u00f3n<\/li>\n<li><b>Servicios externos (Backing Services)<\/b> \u2013 Considere los servicios externos (backing services) como recursos conectables<\/li>\n<li><b>Construcci\u00f3n, lanzamiento, ejecuci\u00f3n<\/b> \u2013 Separe estrictamente las etapas de construcci\u00f3n y ejecuci\u00f3n<\/li>\n<li><b>Procesos<\/b> \u2013 Ejecute la aplicaci\u00f3n como uno o varios procesos sin estado (stateless) <\/li>\n<li><b>Vinculaci\u00f3n de puertos (Port binding)<\/b> \u2013 Exporte servicios a trav\u00e9s de la vinculaci\u00f3n de puertos <\/li>\n<li><b>Paralelismo<\/b> \u2013 Escale la aplicaci\u00f3n mediante procesos <\/li>\n<li><b>Desechabilidad (Disposability)<\/b> \u2013 Maximice la fiabilidad mediante un inicio r\u00e1pido y una correcta finalizaci\u00f3n <\/li>\n<li><b>Paridad entre el desarrollo y la operaci\u00f3n de la aplicaci\u00f3n<\/b> \u2013 Mantenga los entornos de desarrollo, despliegue intermedio (staging) y producci\u00f3n lo m\u00e1s parecidos posible <\/li>\n<li><b>Registro (Logs)<\/b> \u2013 Considere el registro como un flujo de eventos<\/li>\n<li><b>Tareas de administraci\u00f3n<\/b> \u2013 Realice tareas de administraci\u00f3n\/gesti\u00f3n mediante procesos \u00fanicos <\/li>\n<\/ol>\n<p>\n<b>Puede obtener m\u00e1s informaci\u00f3n sobre los 12 factores en los siguientes recursos:<\/b><\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">Fuente original<\/a><\/noindex> \u2013 lectura obligada<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/258739\/\">Art\u00edculo en habr. La Aplicaci\u00f3n de Doce Factores \u2014 The Twelve-Factor App<\/a><\/noindex> \u2013 traducci\u00f3n oficial<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460363\/\">Art\u00edculo en habr. 7 factores que faltan en el enfoque de 12 Factores<\/a><\/noindex> \u2013 una nueva perspectiva sobre los 12 factores con el fin de mejorarlos.<\/li>\n<\/ul>\n<p><\/p>\n<h3>\u00bfQu\u00e9 es el despliegue Blue-Green?<\/h3>\n<p>\nEl despliegue Blue-Green es un m\u00e9todo para entregar una aplicaci\u00f3n en <b>producci\u00f3n<\/b> de manera que el cliente final no ve ning\u00fan cambio por su parte. En otras palabras, el despliegue de la aplicaci\u00f3n ocurre sin un <b>tiempo de inactividad<\/b>.<\/p>\n<p>El esquema cl\u00e1sico de BG Deploy se ve como se indica en la imagen a continuaci\u00f3n. <\/p>\n<p><img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/8252356ac93ce40b248ab27982754985.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Al inicio hay 2 servidores f\u00edsicos con exactamente el mismo c\u00f3digo, aplicaci\u00f3n, proyecto, y hay un enrutador (balanceador). <\/li>\n<li>El enrutador inicialmente dirige todas las solicitudes a uno de los servidores (<b>verde<\/b>). <\/li>\n<li>En el momento en que se necesita volver a realizar un lanzamiento, todo el proyecto se actualiza en el otro servidor (<b>azul<\/b>), que en ese momento no est\u00e1 procesando ninguna solicitud. <\/li>\n<li>Despu\u00e9s de que el c\u00f3digo en <b>el servidor azul<\/b> ha sido completamente actualizado, se le da una orden al enrutador de que debe cambiar del <b>servidor verde<\/b> en <b>azul<\/b> servidor. <\/li>\n<li>Ahora todos los clientes ven el resultado del trabajo del c\u00f3digo en <b>el servidor azul<\/b> Ejecutan ataques m\u00f3viles. <\/li>\n<li> Por un tiempo, <b>verde<\/b> el servidor sirve como copia de seguridad en caso de un despliegue fallido en <b>azul<\/b> el servidor y en caso de fallos o errores, el enrutador cambia el flujo de usuarios de nuevo al <b>verde<\/b> servidor con la versi\u00f3n estable anterior, y el nuevo c\u00f3digo se env\u00eda para su desarrollo y pruebas.<\/li>\n<li>Y al final del proceso, de la misma manera se actualiza <b>verde<\/b> el servidor. Y despu\u00e9s de su actualizaci\u00f3n, el enrutador cambia el flujo de solicitudes de vuelta al <b>verde<\/b> servidor.<\/li>\n<\/ul>\n<p>\nTodo esto se ve muy bien y a primera vista no deber\u00eda haber problemas con ello.<br \/>\nPero ya que vivimos en un mundo moderno, la opci\u00f3n de cambio f\u00edsico como se indica en el esquema cl\u00e1sico no nos conviene. Fijen esta informaci\u00f3n por ahora, volveremos a ella m\u00e1s tarde.<\/p>\n<h3>Consejos buenos y malos<\/h3>\n<p>\n<i>Descargo de responsabilidad<\/i>: En los ejemplos a continuaci\u00f3n se enumeran herramientas \/ metodolog\u00edas que utilizo, pueden usar alternativas absolutamente cualquieras con funciones similares. <\/p>\n<p>La mayor parte de los ejemplos de una manera u otra se cruzar\u00e1 con el desarrollo web (vaya, sorpresa), con PHP y Docker.<\/p>\n<p>Los puntos a continuaci\u00f3n ofrecen una simple descripci\u00f3n pr\u00e1ctica del uso de factores en ciertos ejemplos, si desean obtener m\u00e1s teor\u00eda sobre este tema, consulten las fuentes arriba. <\/p>\n<h4>1. Base de c\u00f3digo<\/h4>\n<p>\nUsen FTP y FileZilla para cargar archivos en los servidores uno por uno, no almacenen el c\u00f3digo en ning\u00fan lugar excepto en el servidor de producci\u00f3n.<\/p>\n<p>El proyecto siempre debe tener una \u00fanica base de c\u00f3digo, es decir, todo el c\u00f3digo proviene de uno solo. <b>Git<\/b> repositorio. Los servidores (producci\u00f3n, staging, prueba1, prueba2\u2026) utilizan c\u00f3digo de ramas de un repositorio com\u00fan. As\u00ed logramos la consistencia del c\u00f3digo.<\/p>\n<h4>2. Dependencias<\/h4>\n<p>\nDescargue todas las bibliotecas en carpetas directamente en la ra\u00edz del proyecto. Las actualizaciones se realizan simplemente trasladando el nuevo c\u00f3digo a la carpeta de la versi\u00f3n actual de la biblioteca. Instale todas las utilidades directamente en el servidor de alojamiento donde funcionan otras 20 aplicaciones.<\/p>\n<p>El proyecto siempre debe tener una lista de dependencias clara y comprensible (por dependencias tambi\u00e9n entiendo el entorno). Todas las dependencias deben estar claramente definidas y aisladas. <br \/>\nComo ejemplo tomaremos <b>Composer<\/b> y <b>Docker<\/b>.<\/p>\n<p><b>Composer<\/b> \u2014 un gestor de paquetes que permite instalar bibliotecas en PHP. Composer permite especificar versiones de manera estricta o no estricta, y definirlas expl\u00edcitamente. En el servidor pueden existir 20 proyectos diferentes y cada uno tendr\u00e1 su propia lista de paquetes y bibliotecas, sin depender de los dem\u00e1s.<\/p>\n<p><b>Docker<\/b> \u2014 una utilidad que permite definir y aislar el entorno en el que funcionar\u00e1 la aplicaci\u00f3n. Por lo tanto, al igual que con Composer, pero de manera m\u00e1s exhaustiva, podemos definir con qu\u00e9 trabaja la aplicaci\u00f3n. Seleccionar una versi\u00f3n espec\u00edfica de PHP, instalar solo los paquetes necesarios para el proyecto sin a\u00f1adir nada extra. Y lo m\u00e1s importante, no mezclarse con los paquetes y el entorno de la m\u00e1quina host y otros proyectos. Es decir, todos los proyectos en el servidor que funcionan a trav\u00e9s de Docker pueden utilizar cualquier conjunto de paquetes y un entorno completamente diferente.<\/p>\n<h4>3. Configuraci\u00f3n<\/h4>\n<p>\nAlmacene las configuraciones como constantes directamente en el c\u00f3digo. Constantes separadas para el servidor de prueba y separadas para producci\u00f3n. Vincule el funcionamiento de la aplicaci\u00f3n a las dependencias del entorno directamente en la l\u00f3gica empresarial del proyecto utilizando construcciones if else.<\/p>\n<p><b>Configuraciones<\/b> \u2014 es lo \u00fanico que deber\u00eda diferenciar los despliegues del proyecto (deployment). Idealmente, las configuraciones deber\u00edan transmitirse a trav\u00e9s de variables de entorno (env vars). <\/p>\n<p>Es decir, incluso si almacenas varios archivos de configuraci\u00f3n .config.prod, .config.local y los renombras al momento de desplegar a .config (la configuraci\u00f3n principal de la cual la aplicaci\u00f3n lee los datos) \u2014 este no ser\u00eda un enfoque correcto, ya que de esa manera la informaci\u00f3n de las configuraciones estar\u00e1 p\u00fablicamente accesible para todos los desarrolladores de la aplicaci\u00f3n y los datos del servidor de producci\u00f3n estar\u00e1n comprometidos. Todas las configuraciones deben almacenarse directamente en el sistema de despliegue (CI\/CD) y generarse para diferentes entornos con los distintos valores necesarios para cada entorno precisamente en el momento del despliegue.<\/p>\n<h4>4. Servicios Externos (Backing Services)<\/h4>\n<p>\nEstablece una fuerte dependencia del entorno, utiliza diferentes conexiones para los mismos servicios en entornos espec\u00edficos.<\/p>\n<p>De hecho, este punto se superpone en gran medida con el punto sobre las configuraciones, ya que sin este punto no se pueden crear datos de configuraci\u00f3n apropiados y la posibilidad de configurar se perder\u00eda por completo.<\/p>\n<p>Todas las conexiones a servicios externos, como servidores de colas, bases de datos, y servicios de cach\u00e9 deben ser iguales tanto para el entorno local como para el entorno externo\/producci\u00f3n. En otras palabras, en cualquier momento, puedo cambiar la cadena de conexi\u00f3n de la base #1 a la base #2 sin modificar el c\u00f3digo de la aplicaci\u00f3n. O adelant\u00e1ndome, como ejemplo, al escalar el servicio, no tendr\u00e1s que especificar la conexi\u00f3n de un servidor de cach\u00e9 adicional de una manera especial.<\/p>\n<h4>5. Compilaci\u00f3n, Lanzamiento, Ejecuci\u00f3n<\/h4>\n<p>\nTen solo la versi\u00f3n final del c\u00f3digo en el servidor, sin posibilidad de revertir el lanzamiento. No hay que ocupar espacio en disco. \u00a1Quien piensa que puede lanzar c\u00f3digo en producci\u00f3n con un error, es un mal programador!<\/p>\n<p>Todas las etapas de despliegue deben estar separadas entre s\u00ed.<\/p>\n<p>Ten la oportunidad de revertir. Realiza lanzamientos conservando copias antiguas de la aplicaci\u00f3n (ya compiladas y listas para producci\u00f3n), para que en caso de errores puedas restaurar la versi\u00f3n anterior. Es decir, hay una carpeta <i>releases<\/i> y una carpeta <i>corriente<\/i>, y despu\u00e9s de un despliegue y compilaci\u00f3n exitosos, la carpeta <i>corriente<\/i> se enlaza con un enlace simb\u00f3lico al nuevo lanzamiento que est\u00e1 dentro de <i>releases<\/i> con un nombre condicional del n\u00famero de lanzamiento. <\/p>\n<p>Aqu\u00ed es donde recordamos el despliegue Blue-Green, que no solo permite cambiar entre el c\u00f3digo, sino tambi\u00e9n entre todos los recursos e incluso entornos, con la posibilidad de revertir todo.<\/p>\n<h4>6. Procesos<\/h4>\n<p>\nGuarde los datos del estado de la aplicaci\u00f3n directamente en la propia aplicaci\u00f3n. Utilice sesiones en la memoria del propio aplicativo. Utilice tanto como sea posible recursos compartidos entre servicios externos. Sujete la idea de que la aplicaci\u00f3n solo puede tener un proceso y evite la posibilidad de escalar.<\/p>\n<p>En cuanto a las sesiones, almacene los datos \u00fanicamente en cach\u00e9s controladas por servicios externos (memcached, redis), de esta manera, incluso si tiene 20 procesos de la aplicaci\u00f3n en ejecuci\u00f3n, cualquiera de ellos, al acceder a la cach\u00e9, podr\u00e1 continuar trabajando con el cliente en el mismo estado en que el usuario estaba interactuando con la aplicaci\u00f3n en otro proceso. Con este enfoque, no importa cu\u00e1ntas copias de servicios externos est\u00e9 utilizando, todo funcionar\u00e1 normalmente sin problemas de acceso a los datos.<\/p>\n<h4>7. Vinculaci\u00f3n de puertos (Port binding)<\/h4>\n<p>\nEl \u00fanico que debe saber c\u00f3mo trabajar con servicios externos es el servidor web. Mejor a\u00fan, levante los servicios externos directamente dentro del servidor web. Por ejemplo, como un m\u00f3dulo PHP en Apache.<br \/>\nTodos sus servicios deben ser accesibles entre s\u00ed a trav\u00e9s de un determinado direcci\u00f3n y puerto (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), es decir, desde nginx puedo acceder tanto a php-fpm como a postgres, y desde php-fpm hacia postgres y nginx; y, de hecho, desde cada servicio puedo acceder a otro servicio. As\u00ed, la viabilidad de un servicio no depende de la viabilidad de otro servicio.<\/p>\n<h4>8. Paralelismo<\/h4>\n<p>\nTrabaje con un solo proceso, porque si no, puede que varios procesos no se lleven bien entre s\u00ed. <\/p>\n<p>Deje abierta la posibilidad de escalar. Docker Swarm es ideal para esto. <br \/>\nDocker Swarm es una herramienta para crear y gestionar cl\u00fasteres de contenedores, tanto entre diferentes m\u00e1quinas como en un gran n\u00famero de contenedores en una sola m\u00e1quina.<\/p>\n<p>Usando swarm, puedo determinar cu\u00e1ntos recursos asignar\u00e9 a cada proceso y cu\u00e1ntos procesos del mismo servicio iniciar\u00e9, y el balanceador interno, al recibir datos en un puerto designado, los proxear\u00e1 autom\u00e1ticamente a los procesos. De esta manera, al ver que la carga en el servidor ha aumentado, puedo agregar m\u00e1s procesos, reduciendo as\u00ed la carga en ciertos procesos.<\/p>\n<h4>9. Descartabilidad (Disposability)<\/h4>\n<p>\nNo utilice colas para trabajar con procesos y datos. La terminaci\u00f3n de un proceso debe afectar el funcionamiento de toda la aplicaci\u00f3n. Si un servicio cae, todo cae.<\/p>\n<p>Cada proceso y servicio puede ser apagado en cualquier momento y eso no debe afectar a otros servicios (no me refiero a que un servicio no est\u00e9 disponible para otro servicio, sino a que otro servicio no se apague junto con este). Todos los procesos deben finalizarse suavemente, de manera que al terminar no se comprometan los datos y, al reiniciarse, el sistema funcione correctamente. Es decir, incluso en caso de un cierre inesperado, los datos no deben verse afectados (aqu\u00ed es donde entra el mecanismo de transacciones; las consultas a la base de datos solo funcionan en grupos, y si al menos una consulta del grupo falla o se ejecuta con error, entonces ninguna otra consulta del grupo se ejecuta realmente).<\/p>\n<h4>10. Paridad entre desarrollo\/operaciones de aplicaci\u00f3n<\/h4>\n<p>\nLa versi\u00f3n de producci\u00f3n, la de staging y la local de la aplicaci\u00f3n deben ser diferentes. En producci\u00f3n tenemos el framework Yii Lite, mientras que localmente usamos Yii, \u00a1para que en producci\u00f3n funcione m\u00e1s r\u00e1pido!<\/p>\n<p>De hecho, todos los despliegues y el trabajo con el c\u00f3digo deben estar en un entorno casi id\u00e9ntico (no se refiere al hardware f\u00edsico). Adem\u00e1s, cualquier miembro del equipo de desarrollo debe ser capaz de desplegar el c\u00f3digo en producci\u00f3n, no solo un departamento de devops entrenado especialmente, que solo puede levantar la aplicaci\u00f3n en producci\u00f3n gracias a un poder especial.<\/p>\n<p>Esto tambi\u00e9n es facilitado por Docker. Al seguir todos los puntos anteriores, el uso de Docker har\u00e1 que el proceso de despliegue del entorno, tanto en producci\u00f3n como en la m\u00e1quina local, se reduzca a ingresar uno o dos comandos.<\/p>\n<h4>11. Registro (Logs)<\/h4>\n<p>\n\u00a1Escribimos logs en archivos y en la base de datos! No limpiamos archivos ni la base de datos de logs. Simplemente compraremos un disco duro de 9000 petabytes y listo.<\/p>\n<p>Todos los registros deben considerarse como un flujo de eventos. La aplicaci\u00f3n misma no debe encargarse de procesar los registros. Los registros deben enviarse ya sea a stdout, o enviarse a trav\u00e9s de un protocolo como udp, de modo que el trabajo de la aplicaci\u00f3n con los registros no cree ning\u00fan problema. Graylog es una buena opci\u00f3n para esto. Graylog, al recibir todos los registros por udp (con este protocolo no se requiere esperar una respuesta de confirmaci\u00f3n de recepci\u00f3n del paquete) no interfiere con la aplicaci\u00f3n de ninguna manera y se encarga \u00fanicamente de estructurar y procesar los registros. La l\u00f3gica de la aplicaci\u00f3n no cambia para trabajar con este tipo de enfoques.<\/p>\n<h4>12. Tareas de administraci\u00f3n<\/h4>\n<p>\nPara actualizar datos, bases de datos, etc., utilice un endpoint creado por separado en la API, cuya ejecuci\u00f3n dos veces seguidas puede causar que todo se duplique. Pero ustedes no son tontos, no har\u00e1n clic dos veces, y las migraciones no son necesarias.<\/p>\n<p>Todas las tareas de administraci\u00f3n deben realizarse en el mismo entorno que todo el c\u00f3digo, a nivel de lanzamientos. Es decir, si necesitamos cambiar la estructura de la base de datos, no lo haremos manualmente, cambiando el nombre de las columnas y agregando nuevas a trav\u00e9s de herramientas visuales de gesti\u00f3n de bases de datos. Para tales cosas, creamos scripts separados \u2014 migraciones, que se ejecutan en todos los entornos de la misma manera y con un resultado claro y comprensible. Para todas las dem\u00e1s tareas, como llenar el proyecto con datos, deben aplicarse metodolog\u00edas similares.<\/p>\n<h3>Ejemplo de implementaci\u00f3n en PHP, Laravel, Laradock, Docker-Compose<\/h3>\n<p>\nP.D. Todos los ejemplos se hicieron en MacOS. La mayor parte tambi\u00e9n es aplicable a Linux. Usuarios de Windows, lo siento, pero no he trabajado con Windows desde hace tiempo.<\/p>\n<p>Imaginemos que en nuestra PC no est\u00e1 instalada ninguna versi\u00f3n de PHP y, de hecho, no hay nada. <br \/>\nInstalamos las \u00faltimas versiones de docker y docker-compose. (esto se puede encontrar en Internet)<\/p>\n<pre><code class=\"bash\">docker -v &amp;&amp; \ndocker-compose -v\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y 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=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/67b3214d9a5cff4596c4914ea6e199c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSobre Laradock, dir\u00e9 que es una herramienta excelente, que incluye muchos contenedores y utilidades. Pero no recomendar\u00eda usar Laradock tal cual en producci\u00f3n debido a su sobrecarga. Es mejor crear sus propios contenedores bas\u00e1ndose en los ejemplos de Laradock, ya que as\u00ed habr\u00e1 m\u00e1s espacio para optimizar, porque a nadie le sirve tener todo lo que hay all\u00ed al mismo tiempo.<\/p>\n<p>2. Configuramos Laradock para que trabaje con nuestra aplicaci\u00f3n.<\/p>\n<pre><code class=\"bash\">cd laradock &amp;&amp; \ncp env-example .env\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/df8107e1be933cc955be8ca5066f22f2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.1. Abrimos el directorio habr (la carpeta principal donde se clon\u00f3 laradock) en cualquier editor. (En mi caso, PHPStorm)<\/p>\n<p>En esta etapa, solo asignamos un nombre al proyecto.<\/p>\n<p><img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/f6026fd04130590539e0945db30ec0dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.2. Iniciamos la imagen del workspace. (En su caso, las im\u00e1genes estar\u00e1n construy\u00e9ndose por un tiempo)<br \/>\nWorkspace es una imagen especialmente preparada para trabajar con el framework como desarrollador.<\/p>\n<p>Entramos en el contenedor 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=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/e839a5cd055b6c06c02cdd03a5054477.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.3. Instalamos Laravel<\/p>\n<pre><code class=\"bash\">composer create-project --prefer-dist laravel\/laravel application<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/b21b3fc30ce1bec63aee43ab5fce53e3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.4. Despu\u00e9s de la instalaci\u00f3n, verificamos si se ha creado el directorio del proyecto y detenemos el compose.<\/p>\n<pre><code class=\"bash\">ls\nexit\ndocker-compose down\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/e812f383138637656ec96804833cfc53.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.5. Regresamos a PHPStorm y establecemos la ruta correcta a nuestra aplicaci\u00f3n Laravel en el archivo .env.<\/p>\n<p><img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/abb9a5694d01163960af5375767f331b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n3. Agregamos todo el c\u00f3digo a Git.<\/p>\n<p>Para ello, creamos un repositorio en GitHub (o en cualquier otro lugar). Vamos a la terminal, al directorio habr, y ejecutamos el siguiente c\u00f3digo.<\/p>\n<pre><code class=\"bash\">echo \"# habr-12factor\" &gt;&gt; README.md\ngit init\ngit add README.md\ngit commit -m \"primer commit\"\ngit remote add origin git@github.com:nzulfigarov\/habr-12factor.git # aqu\u00ed estar\u00e1 el enlace a tu repositorio\ngit push -u origin master\ngit status\n<\/code><\/pre>\n<p>\nVerificamos que todo est\u00e9 en orden. <\/p>\n<p><img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/cbcb770a95d91655bdaf727be79742ab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPara mayor comodidad, recomiendo usar alguna interfaz visual para Git, en mi caso es <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gitkraken.com\/invite\/qXBXV9Wm\">GitKraken<\/a><\/noindex>. (aqu\u00ed est\u00e1 el enlace de referencia)<\/p>\n<p>4. \u00a1Arrancamos!<\/p>\n<p>Antes de iniciar, aseg\u00farese de que no haya nada ocupado en los puertos 80 y 443.<\/p>\n<pre><code class=\"bash\">docker-compose up -d nginx php-fpm<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/f0bf0416e67b918e0966100e37c74454.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDe este modo, nuestro proyecto consta de 3 servicios separados:<\/p>\n<ul>\n<li>nginx \u2014 servidor web<\/li>\n<li>php-fpm \u2014 php para procesar peticiones desde el servidor web<\/li>\n<li>workspace \u2014 php para el desarrollador<\/li>\n<\/ul>\n<p>\nHasta ahora hemos logrado crear una aplicaci\u00f3n que cumple con los 4 puntos de los 12, a saber:<\/p>\n<p>1. <b>Base de c\u00f3digo<\/b> \u2014 todo el c\u00f3digo est\u00e1 en un \u00fanico repositorio (una peque\u00f1a observaci\u00f3n: posiblemente ser\u00eda correcto incluir docker dentro del proyecto laravel, pero no es esencial).<\/p>\n<p>2. <b>Dependencias<\/b> \u2014 Todas nuestras dependencias est\u00e1n claramente especificadas en application\/composer.json y en cada Dockerfile de cada contenedor.<\/p>\n<p>3. <b>Servicios externos (Backing Services)<\/b> \u2014 Cada uno de los servicios (php-fpm, nginx, workspace) vive su propia vida y est\u00e1 conectado externamente, por lo que al trabajar con un servicio, otro no ser\u00e1 afectado.<\/p>\n<p>4. <b>Procesos<\/b> \u2014 cada servicio es un proceso \u00fanico. Ninguno de los servicios guarda estado interno.<\/p>\n<p>5.<b> Vinculaci\u00f3n de puertos (Port binding)<\/b><\/p>\n<pre><code class=\"bash\">docker ps\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/e6e3fa4a12a43d1bcd51992c424c1245.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComo vemos, cada servicio est\u00e1 corriendo en su propio puerto y es accesible para todos los dem\u00e1s servicios.<\/p>\n<p>6.<b> Paralelismo <\/b><\/p>\n<p>Docker nos permite levantar m\u00faltiples procesos de los mismos servicios con balanceo de carga autom\u00e1tica entre ellos. <\/p>\n<p>Detendremos los contenedores y los reiniciaremos con el 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=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/f5d279b8a034512dd20024272c7f03b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nComo podemos ver, se han creado copias del contenedor php-fpm. No necesitamos cambiar nada en el trabajo con este contenedor. Continuamos accediendo a \u00e9l a trav\u00e9s del puerto 9000, y Docker gestiona la carga entre los contenedores por nosotros.<\/p>\n<p>7. <b>Desechabilidad (Disposability)<\/b> \u2014 se puede eliminar cada contenedor sin afectar a los dem\u00e1s. Detener o reiniciar un contenedor no impactar\u00e1 en el funcionamiento de la aplicaci\u00f3n en ejecuciones posteriores. Cada contenedor tambi\u00e9n se puede levantar en cualquier momento.<\/p>\n<p>8. <b>Paridad entre el desarrollo y la operaci\u00f3n de la aplicaci\u00f3n<\/b> \u2014 todos nuestros entornos son id\u00e9nticos. Al ejecutar el sistema en el servidor de producci\u00f3n, no tendr\u00e1s que cambiar nada en tus comandos. Todo estar\u00e1 basado exactamente igual en Docker.<\/p>\n<p>9. <b>Registro (Logs)<\/b> \u2014 todos los logs en estos contenedores se env\u00edan a un flujo y son visibles en la consola de Docker. (en este caso, en realidad, con otros contenedores personalizados, puede que no sea as\u00ed si no te ocupas de ello)<\/p>\n<pre><code class=\"bash\"> docker-compose logs -f<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/67e275042b96f5270534466b426d4fdc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSin embargo, hay un inconveniente: los valores predeterminados en PHP y Nginx tambi\u00e9n registran logs en un archivo. Para cumplir con los 12 factores, es necesario <b>desactivar<\/b> registrar logs en archivos en la configuraci\u00f3n de cada contenedor por separado.<\/p>\n<p>Docker tambi\u00e9n ofrece la posibilidad de dirigir logs no solo a stdout, sino tambi\u00e9n a herramientas como graylog de las que habl\u00e9 anteriormente. Dentro de graylog, podemos manejar los logs como queramos y nuestra aplicaci\u00f3n no se ver\u00e1 afectada por eso.<\/p>\n<p>10. <b>Tareas de administraci\u00f3n<\/b> \u2014 todas las tareas de administraci\u00f3n se resuelven en Laravel gracias a la herramienta artisan tal como lo habr\u00edan deseado los creadores de la aplicaci\u00f3n de 12 factores.<\/p>\n<p>Como ejemplo, mostrar\u00e9 c\u00f3mo se ejecutan algunos comandos.<br \/>\nEntramos en el contenedor.<\/p>\n<pre><code class=\"bash\"> \ndocker-compose exec workspace bash\nphp artisan list\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/3d5fb5bc40b4b8b0cb225116c0f3d625.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAhora podemos usar cualquier comando. (ten en cuenta que no configuramos la base de datos y la cach\u00e9, por lo que la mitad de los comandos no se ejecutar\u00e1n correctamente, ya que est\u00e1n destinados a trabajar con cach\u00e9 y bdd).<\/p>\n<p><img decoding=\"async\" alt=\"Desarrollo de aplicaciones y Blue-Green deployment, basado en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker\" src=\"\/wp-content\/uploads\/2020\/02\/6f84bb2ade2ade654d2c361c585edeae.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n11. <b>Configuraciones<\/b> y 12. <b>Construcci\u00f3n, lanzamiento, ejecuci\u00f3n<\/b><\/p>\n<p>Esta parte quer\u00eda dedicarla al Blue-Green Deployment, pero result\u00f3 ser demasiado extensa para este art\u00edculo. Escribir\u00e9 un art\u00edculo separado sobre ello. <\/p>\n<p>En pocas palabras, el concepto se basa en sistemas de CI\/CD como <b>Jenkins<\/b> y <b>Gitlab CI<\/b>. En ambos se pueden definir variables de entorno relacionadas con el entorno espec\u00edfico. Por lo tanto, en tal disposici\u00f3n se cumplir\u00e1 el punto sobre <b>Configuraciones<\/b>.<\/p>\n<p>Y el punto sobre <b>Construcci\u00f3n, lanzamiento, ejecuci\u00f3n<\/b> se resuelve con funciones integradas en ambas herramientas llamadas <b>Pipeline<\/b>.<\/p>\n<p><b>Pipeline<\/b> permite dividir el proceso de despliegue en m\u00faltiples etapas, destacando las fases de construcci\u00f3n, lanzamiento y ejecuci\u00f3n. Tambi\u00e9n en el Pipeline, podr\u00e1 crear copias de seguridad, y en general, cualquier cosa. Esta herramienta tiene un potencial ilimitado.<\/p>\n<p>El c\u00f3digo de la aplicaci\u00f3n se encuentra en <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nzulfigarov\/habr-12factor\">Github<\/a><\/noindex>.<br \/>\nNo olvide inicializar el subm\u00f3dulo al clonar este repositorio.<\/p>\n<p>P.D.: Todos estos enfoques se pueden utilizar con cualquier otra herramienta y lenguajes de programaci\u00f3n. Lo importante es que la esencia no cambie.<br \/>\n<br \/>Fuente: <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 - 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\/es\/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\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47Desarrollo de aplicaciones y implementaci\u00f3n Blue-Green, bas\u00e1ndose en la metodolog\u00eda The Twelve-Factor App con ejemplos en php y docker | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/es\/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":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/40596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=40596"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/40596\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/40597"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=40596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=40596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=40596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}