Implemente aplicaciones de Symfony + React en AWS a través de CI

Buenas tardes, en este artículo mostraré cómo implementar la aplicación Symfony 4 en AWS. Hay un ejemplo de dicho proceso en la documentación oficial, pero mi versión no es tan trivial como descargar un archivo zip con una aplicación. En el patio de 2019, en modo acoplable, la arquitectura de microservicios y las prácticas de CI / CD finalmente comienzan a incluirse en las herramientas no solo de los ingenieros de DevOps, sino también de los desarrolladores mortales comunes. Para hacer el artículo más interesante, agregué un frente a React.JS, para cubrir las necesidades de más personas, si su aplicación no usa Encore - no importa, le indicaré cómo cambiar el archivo Docker para usted, el soporte para React.JS solo lo afecta . ¿Quién estará interesado en este tutorial? En primer lugar, está dirigido a los desarrolladores de PHP que desean cambiar su práctica de implementación: alejarse de los cánones habituales y usar docker para empacar su aplicación y diseñar la imagen. Pero puede profundizar un poco más, y la narración adicional tendrá como objetivo implementar automáticamente la aplicación desde Git a través de la plataforma CI / CD (se utilizará CircleCI, pero si está interesado en la configuración de Gitlab, escriba los comentarios, lo adjuntaré). De hecho, no es absolutamente importante para React / PHP si tiene una aplicación o, por ejemplo, .NET Core, esta parte será interesante para que los desarrolladores adquieran habilidades de automatización de implementación en general. El código fuente está disponible en el repositorio de github, enlace al final del artículo. Bueno, vamos!

Supongo que tiene su propia aplicación Symfony, pero para los propósitos de demostración esbocé "hola, mundo!" Que contiene los siguientes paquetes:

`symfony/webpack-encore-bundle symfony/form symfony/orm-pack symfony/profiler-pack symfony/security-bundle symfony/twig-bundle symfony/validator symfony/phpunit-bridge` es un conjunto de caballeros mínimo. Por el momento, la estructura de la carpeta debe ser la siguiente:

imagen

Ahora necesita configurar su infraestructura en la nube. No me enfocaré en registrar y activar el período de prueba de AWS, en esta etapa necesitamos crear 2 instancias de DB. Usaré 2 tipos de entorno: STG (puesta en escena) para probar la implementación de nuevas "características" y PROD (producción) como directamente "combate". servidor Se han escrito muchos artículos sobre los beneficios de la base de datos de servicios administrados, además, principalmente buscamos la conveniencia para el desarrollador en esta guía, por lo tanto, utilizamos RDS, en lugar de crear nuestro propio servidor de base de datos separado. Como DBMS para este ejemplo, utilicé PostgreSQL, puede elegir el que más le convenga, ir al servicio RDS y crear 2 instancias de la capacidad y el volumen que necesita. Dado que el archivo .env está disponible para nosotros " .env para usar" en Symfony, lo usaremos, por ejemplo, para PROD, y para STG crearemos una copia de .env.stg y cambiaremos APP_ENV=dev a APP_ENV=stg en .env.stg y APP_ENV=dev en APP_ENV=prod en .env y también ingrese los parámetros de conexión de la .env para cada una de las instancias creadas.

¡Genial, se ha comenzado! Como sabes, las dependencias de Symfony se instalan a través de Composer, para instalarlo, usa el archivo composer.sh, que colocamos en la raíz del proyecto:

composer.sh
 #!/bin/sh EXPECTED_SIGNATURE="$(wget -q -O - https://composer.imtqy.com/installer.sig)" php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] then >&2 echo 'ERROR: Invalid installer signature' rm composer-setup.php exit 1 fi php composer-setup.php --quiet RESULT=$? rm composer-setup.php exit $RESULT 


Esta es una guía de instalación de software del compositor .

Ahora, para cada uno de los entornos, cree su propio Dockerfile en la raíz del proyecto:

Dockerfile.stg (puesta en escena)
 FROM php:7.2.19-apache EXPOSE 80 RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && a2enmod rewrite RUN sed -ri -e 's!memory_limit = 128M!memory_limit = 256M!g' "$PHP_INI_DIR/php.ini" RUN apt-get update && apt-get install -y \ wget \ curl \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libzip-dev \ zip \ libpq-dev \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-configure zip --with-libzip \ && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install zip \ && docker-php-ext-install pdo pdo_pgsql pgsql WORKDIR /var/www ENV APACHE_DOCUMENT_ROOT /var/www/public RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf COPY ./composer.sh ./ RUN chmod +x ./composer.sh && ./composer.sh && mv composer.phar /usr/local/bin/composer RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ && apt-get install -y nodejs RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ && apt-get update -qq \ && apt-get install -y yarn COPY ./ ./ COPY ./.env.stg ./.env RUN composer install && yarn && yarn run build 


y

Dockerfile (producción)
 FROM php:7.2.19-apache EXPOSE 80 RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && a2enmod rewrite RUN sed -ri -e 's!memory_limit = 128M!memory_limit = 256M!g' "$PHP_INI_DIR/php.ini" RUN apt-get update && apt-get install -y \ wget \ curl \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libzip-dev \ zip \ libpq-dev \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-configure zip --with-libzip \ && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install zip \ && docker-php-ext-install pdo pdo_pgsql pgsql WORKDIR /var/www ENV APACHE_DOCUMENT_ROOT /var/www/public RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf COPY ./composer.sh ./ RUN chmod +x ./composer.sh && ./composer.sh && mv composer.phar /usr/local/bin/composer RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ && apt-get install -y nodejs RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ && apt-get update -qq \ && apt-get install -y yarn COPY ./ ./ RUN composer install && yarn && yarn run build 


Los archivos se pueden usar "tal cual", no se usan macros para los cambios. Veamos el contenido del Dockerfile para disipar el toque "mágico". Como "base", utilizamos la imagen oficial de PHP 7.2.19 con el servidor web Apache integrado (puede usar cualquiera de sus opciones, configurar un paquete con Nginx, etc.). En este ejemplo, utilizo lo anterior como máximo, en mi opinión, conveniente). La línea de exposición no es importante para nosotros en este momento, por sí sola no hace nada, pero en el futuro será utilizada por ElasticBeanstalk, que necesita desplegarse correctamente. Las siguientes construcciones utilizan configuraciones de producción optimizadas para PHP recomendadas por el fabricante, activan mod_rewrite para Apache y aumentan el tamaño máximo de memoria para un script PHP de 128 a 256 mb, que es necesario para que el compositor funcione correctamente. A continuación, instalamos las aplicaciones necesarias, las dependencias y extensiones de PHP, y las configuramos de inmediato. Asignamos la carpeta / var / www al directorio de trabajo de nuestra aplicación; el código fuente de nuestra aplicación se copiará allí. Como apache, por defecto, usa / var / www como punto de entrada para su host, y el archivo de índice de Symfony se encuentra en / var / www / public, cambiamos la raíz del documento de apache con la siguiente construcción. Luego instalamos composer, nodejs e hilo secuencialmente (si no usa encore / react.js en su aplicación, entonces no necesita los dos últimos puntos). Finalmente, copiamos nuestro código fuente y comenzamos la instalación de dependencias a través del compositor para Symfony y Yarn para react.js. El significado de un Dockerfile separado para STG reside en las penúltimas instrucciones para docker: copiar .env.stg a .env, por lo que el archivo .env en la imagen STG contendrá los parámetros relevantes para este entorno. Puede recolectar localmente (por supuesto, con Docker instalado) la imagen, ejecutarla y asegurarse de que la aplicación funciona y no necesita nada más para este trabajo:

 docker build -t tmp:stg -f Dockerfile.stg . docker run -p 80:80 tmp:stg 

para STG y

 docker build -t tmp:prod . docker run -p 80:80 tmp:prod 

para PROD.
Podemos usar EC2, configurar ELB / ASG, etc., o usar ElasticBeanstalk, que es solo un regalo para nosotros en términos de conveniencia. Vaya a la sección ElasticBeanstalk y cree una nueva aplicación con su nombre y descripción. Luego, cree 2 entornos que se mencionaron anteriormente: STG y PROD, cree ambos entornos como un entorno de servidor web, especifique "Docker" como plataforma y deje la aplicación de muestra como el código de la aplicación. La implementación en ElasticBeanstalk se realiza cargando archivos de proyecto o instrucciones, generalmente en un archivo zip. En nuestro caso, el flujo será así: recopilamos la imagen del acoplador de nuestra aplicación, la cargamos en el repositorio y cargamos las instrucciones en lugar del archivo fuente o la imagen del acoplador, lo que le dice a ElasticBeanstalk que tome la imagen del servidor remoto y la implemente. Y todo esto es automático.

Comencemos creando un repositorio para almacenar imágenes acoplables. Hay 2 opciones:

1 - su proyecto es privado, su código está cerrado y el repositorio, respectivamente, también debe estar cerrado. En este caso, puede mantener su propio registro de imágenes en algún lugar o utilizar una nube privada. AWS tiene ECR para estos fines, puede crear un repositorio allí, pero nadie lo obliga a hacerlo.

2: tiene un proyecto de código abierto y puede usar dockerhub.

En nuestro ejemplo, el código está abierto, pero mostraré cómo usar repositorios cerrados, después de comprender este proceso, conectar una imagen desde dockerhub no será difícil. Lo primero que necesitamos es crear el repositorio en sí, después de eso obtendrá su URI único. La narración adicional irá a terceros (no a los repositorios de AWS ECR y su integración), para ECR escribiré después de eso.

Después de crear el repositorio, necesitamos iniciar sesión en este servicio y hay un pequeño truco ... Vaya a la configuración de su acoplador instalado localmente y verifique que tenga la opción de guardar las contraseñas en el almacenamiento externo eliminado (para usuarios de macOS: "Almacene de forma segura los inicios de los acopladores en macOS Keychain ”), de lo contrario, el archivo de configuración que necesitamos estará vacío. Y así, autorizamos en el servicio seleccionado para almacenar los registros de sus imágenes:

 docker login -u LOGIN -p PASSWORD REGISTRY 

después de una autenticación exitosa, la siguiente construcción aparecerá en el archivo de configuración ~ / .docker / config.json:

 "REGISTRY" : { "auth" : "BASE64_ENCODED_TOKEN" } 

Si no aparece, verifique nuevamente la configuración de la ventana acoplable descrita anteriormente.

Ahora todo está listo para preparar el archivo de instrucciones para ElasticBeanstalk - Dockerrun.aws.json, su código será así:

Dockerrun.aws.json
 { "AWSEBDockerrunVersion": "1", "Authentication": { "Bucket": "BUCKET_ID", "Key": "KEY_PATH" }, "Image": { "Name": "IMAGE_URL", "Update": "true" }, "Ports": [ { "ContainerPort": "80" } ] } 


En general, la instrucción se ve así: después de iniciar sesión con la clave ubicada por KEY_PATH en el BUCKET_ID de almacenamiento S3, cargue la imagen IMAGE_URL sobrescribiendo la guardada, comience enviando el puerto 80 al mismo puerto en el contenedor. Ahora sobre las constantes utilizadas:

BUCKET_ID es la "mochila" creada automáticamente para usted en el servicio S3, que tiene la forma de elasticbeanstalk-REGION-HASH, aquí es donde el sistema localiza los archivos de servicio para su ElasticBeanstalk, incluidos los archivos de aplicación que descarga utilizando el botón "Cargar e implementar".

KEY_PATH: ruta del archivo de autorización al repositorio de imágenes, utilizo el formato APP_NAME / cr.json, es decir, en la carpeta dentro de BUCKET_ID bajo el nombre de mi aplicación (creo, si no todavía) pongo el archivo cr.json que contiene el código recibido después de la autorización en el registro Imágenes a nivel local:

BUCKET_ID / APP_NAME / cr.json
 { "REGISTRY" : { "auth" : "BASE64_ENCODED_TOKEN" } } 

IMAGE_URL es el URI único de su registro de imagen + etiqueta de la imagen en sí, todo debe quedar claro aquí.

Eso es todo, ahora podemos descargar este archivo como una versión de nuestra aplicación en ElasticBeanstalk, y él extraerá la imagen especificada y la implementará.

Queda por automatizar este proceso. Y para ser absolutamente interesante, implementaré la secuencia de pasos para el siguiente flujo: para todos los commits NO en la rama maestra, la imagen se recopilará y desplegará en el entorno STG, y si ingresamos en el maestro, o mejor, lo cierro y lo llenamos con la solicitud de fusión 's, entonces el código se implementará en PROD. Por lo tanto, obtenemos en PROD un asistente actualizado, en el que todo debería estar bien, y se ramifica para desarrollar y probar nuevo código en STG. Para esta implementación, necesitamos instrucciones para cargar imágenes que no sean las últimas, copie Dockerrun.aws.json en Dockerrun.aws.stg.json y cambie el nombre de Dockerrun.aws.json a Dockerrun.aws.prod.json (solo por conveniencia).

Lo único que diferencia a Dockerrun.aws.stg.json de Dockerrun.aws.prod.json es IMAGE_URL:

Dockerrun.aws.stg.json
 { "AWSEBDockerrunVersion": "1", "Authentication": { "Bucket": "BUCKET_ID", "Key": "KEY_PATH" }, "Image": { "Name": "IMAGE_URL:dev", "Update": "true" }, "Ports": [ { "ContainerPort": "80" } ] } 


Como dije al comienzo del artículo, usaré CircleCI como un CI / CD, que, según mis sentimientos personales, es más rápido que GitlabCI si uso la versión gratuita de SaaS. Travis libre lo haría, pero como no funciona con repositorios privados de git, no realicé una demostración específica para que no haya decepciones cuando se necesitara esa oportunidad. Dejaré la configuración del proyecto en CircleCI a los lectores para que la estudien de forma independiente, yo mismo daré las instrucciones necesarias para la implementación: en la raíz de nuestro proyecto crearemos la carpeta .circleci, en ella config.yml con el siguiente contenido:

.circleci / config.yml
 version: 2 jobs: build: machine: true steps: - checkout - run: echo "$CI_REGISTRY_PASSWORD" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY - run: docker build -t $CI_REGISTRY/$CI_REGISTRY_ID:dev -f Dockerfile.stg . - run: docker push $CI_REGISTRY/$CI_REGISTRY_ID:dev build-master: machine: true steps: - checkout - run: echo "$CI_REGISTRY_PASSWORD" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY - run: docker build -t $CI_REGISTRY/$CI_REGISTRY_ID:latest . - run: docker push $CI_REGISTRY/$CI_REGISTRY_ID:latest deploy-stg: docker: - image: circleci/python:latest steps: - checkout - run: sudo pip install awsebcli --upgrade - run: | mkdir ~/.aws touch ~/.aws/config chmod 600 ~/.aws/config echo "[profile eb-cli]" > ~/.aws/config echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config - run: eb init --region EB_REGION --platform Docker EB_APP - run: cp Dockerrun.aws.stg.json Dockerrun.aws.json - run: eb use EB_ENV_STG --region EB_REGION - run: eb deploy -v --staged --profile eb-cli deploy-prod: docker: - image: circleci/python:latest steps: - checkout - run: sudo pip install awsebcli --upgrade - run: | mkdir ~/.aws touch ~/.aws/config chmod 600 ~/.aws/config echo "[profile eb-cli]" > ~/.aws/config echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config - run: eb init --region EB_REGION --platform Docker EB_APP - run: cp Dockerrun.aws.prod.json Dockerrun.aws.json - run: eb use EB_ENV_STG --region EB_REGION - run: eb deploy -v --staged --profile eb-cli workflows: version: 2 build: jobs: - build: filters: branches: ignore: - master - deploy-stg: requires: - build filters: branches: ignore: - master build-deploy: jobs: - build-master: filters: branches: only: - master - deploy-prod: requires: - build-master filters: branches: only: - master 

Pinté el flujo en sí un poco antes, aquí está traducido en instrucciones yaml para CircleCI, veamos la implementación de pasos específicos. Es importante tener en cuenta la presencia de variables de entorno definidas para CI que serán utilizadas por él durante el trabajo:

CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD son necesarios para acceder al almacenamiento de imágenes del acoplador, lo mismo que colocamos en cr.json, solo sin base64

CI_REGISTRY / CI_REGISTRY_ID forman una URL de imagen única, sin etiqueta

AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY: los nombres hablan por sí mismos, estos son créditos de AWS para el usuario en cuyo nombre se desplegará CircleCI. Vaya a AWS IAM y cree un usuario, agréguelo al grupo de administradores y proporcione solo acceso programático. Recuerde que AWS_SECRET_ACCESS_KEY está disponible para ver / copiar solo una vez, después de hacer clic en el enlace mostrar, no lo volverá a ver.

Volver a los pasos de configuración de CircleCI. Que es la magia Checkout carga el código fuente de la rama git en el directorio de trabajo actual, este proceso se repite en cada trabajo. En el proceso de compilación, iniciamos sesión secuencialmente en el repositorio, recopilamos el código basado en Dockerfile.stg bajo la etiqueta XXX: dev y lo enviamos al repositorio. build-master hace lo mismo, solo para la compilación, utiliza el Dockerfile "normal" bajo la etiqueta XXX: último.

deploy-stg instala AWS EB CLI y crea un perfil de autorización en el archivo ~ / .aws / config, que es necesario para que la CLI funcione correctamente, luego inicializa las variables para la CLI; deberá especificar la región que elija, la plataforma, siempre Docker y el nombre de su aplicación. A continuación, copiamos el contenido de Dockerrun.aws.stg.json al nuevo archivo Dockerrun.aws.json y, usando el entorno y la región específicos, le damos el comando para implementar nuestra aplicación usando el perfil de autorización creado. De manera predeterminada, como resultado de este comando, todo el código de la rama monitoreada terminará en un archivo zip, que se descargará a ElasticBeanstalk y se desempaquetará allí, pero esta operación es relativamente costosa, por eso creamos un nuevo archivo Dockerrun.aws.json, que es suficiente para implementar el creado por nosotros. imagen remota, y solo necesitamos cargarla, de hecho. Para hacer esto, cree un archivo .ebignore en la raíz del proyecto:

.ebignore
 * !Dockerrun.aws.json 

Este archivo utiliza la sintaxis .gitignore y es .gitignore, pero no para Git CLI, sino para AWS EB CLI. En este archivo, le digo a la CLI que omita todos los archivos excepto Dockerrun.aws.json. Eso es todo, ahora cuando ejecuta el trabajo deploy-stg en ElasticBeanstalk, solo se enviará el archivo que creamos. deploy-prod hace lo mismo, solo copia el contenido del archivo Dockerrun.aws.prod.json a Dockerrun.aws.json, y el último es una indicación de la secuencia de trabajo en el formato CircleCI (deploy-stg después de la compilación y deploy-prod después de la compilación -master), y en qué ramas están buscando los datos (ignore: - master y solo: - master).

Un asunto diferente es con AWS ECR, como prometí, volveremos a ello. No necesita iniciar sesión de forma remota en el ECR y crear un archivo cr.json, ya que ElasticBeanstalk "conoce a un hermano en persona". En consecuencia, Dockerrun.aws.json se verá diferente, simplemente no habrá bloque de autenticación:

Dockerrun.aws.json (AWS ECR)
 { "AWSEBDockerrunVersion": "1", "Image": { "Name": "IMAGE_URL", "Update": "true" }, "Ports": [ { "ContainerPort": "80" } ] } 


Pero, ¿cómo ocurrirá la autenticación? El hecho es que el servicio que accede al ECR tiene un cierto conjunto de derechos, que a su vez se basan en ciertas políticas de seguridad. En nuestro caso, cuando la implementación se inicia a través de la CLI de AWS desde un servidor de terceros (desde CI), se utiliza la función "aws-elasticbeanstalk-ec2-role", encuéntrela en el AWS IAM en la sección de roles y adjunte la política adicional "AmazonEC2ContainerRegistryReadOnly". Ahora la descarga desde un repositorio privado a su "vecino" tendrá éxito sin errores.

Pero esto se carga exactamente desde la misma VPC, a través de la CLI, el comando de inicio de sesión de Docker tampoco está "sin trucos": debe obtener (solo obtener) créditos para el inicio de sesión de Docker a través de la CLI de AWS, para esto hay un comando

aws ecr get-login --region REGION --no-include-email

Este comando le devolverá una línea del formulario de inicio de sesión del acoplador ..., simplemente, en la consola que necesita ejecutar

eval $(aws ecr get-login --region EB_REGION --no-include-email)

El comando primero recibirá una cadena para la autenticación y luego comenzará el proceso correspondiente. En vista de estas reglas para AWS ECR, el archivo de instrucciones para CircleCI se verá así:

.circleci / config.yml (para AWS ECR)
 version: 2 jobs: build: docker: - image: circleci/python:latest steps: - checkout - run: sudo pip install awscli --upgrade - run: | mkdir ~/.aws touch ~/.aws/config chmod 600 ~/.aws/config echo "[profile eb-cli]" > ~/.aws/config echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config - setup_remote_docker - run: eval $(aws ecr get-login --region EB_REGION --no-include-email) - run: docker build -t $CI_REGISTRY/$CI_REGISTRY_ID:dev -f Dockerfile.stg . - run: docker push $CI_REGISTRY/$CI_REGISTRY_ID:dev build-master: docker: - image: circleci/python:latest steps: - checkout - run: sudo pip install awscli --upgrade - run: | mkdir ~/.aws touch ~/.aws/config chmod 600 ~/.aws/config echo "[profile eb-cli]" > ~/.aws/config echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config - setup_remote_docker - run: eval $(aws ecr get-login --region EB_REGION --no-include-email) - run: docker build -t $CI_REGISTRY/$CI_REGISTRY_ID:latest . - run: docker push $CI_REGISTRY/$CI_REGISTRY_ID:latest deploy-stg: docker: - image: circleci/python:latest steps: - checkout - run: sudo pip install awsebcli --upgrade - run: | mkdir ~/.aws touch ~/.aws/config chmod 600 ~/.aws/config echo "[profile eb-cli]" > ~/.aws/config echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config - run: eb init --region EB_REGION --platform Docker EB_APP - run: cp Dockerrun.aws.stg.json Dockerrun.aws.json - run: eb use EB_ENV_STG --region EB_REGION - run: eb deploy -v --staged --profile eb-cli deploy-prod: docker: - image: circleci/python:latest steps: - checkout - run: sudo pip install awsebcli --upgrade - run: | mkdir ~/.aws touch ~/.aws/config chmod 600 ~/.aws/config echo "[profile eb-cli]" > ~/.aws/config echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config - run: eb init --region EB_REGION --platform Docker EB_APP - run: cp Dockerrun.aws.prod.json Dockerrun.aws.json - run: eb use EB_ENV_STG --region EB_REGION - run: eb deploy -v --staged --profile eb-cli workflows: version: 2 build: jobs: - build: filters: branches: ignore: - master - deploy-stg: requires: - build filters: branches: ignore: - master build-deploy: jobs: - build-master: filters: branches: only: - master - deploy-prod: requires: - build-master filters: branches: only: - master 

docker-in-docker setup_remote_docker , . , :

imagen

, , () . «» . ( - ) , , , .

GitHub: tutorial-aws-symfony-ci

Source: https://habr.com/ru/post/462415/


All Articles