Bereitstellen von Symfony + React-Anwendungen auf AWS über CI

Guten Tag, in diesem Artikel werde ich zeigen, wie die Symfony 4-Anwendung unter AWS bereitgestellt wird. Es gibt ein Beispiel für einen solchen Prozess in der offiziellen Dokumentation, aber meine Version ist nicht so trivial wie das Herunterladen eines Zip-Archivs mit einer Anwendung. Im Jahr 2019 werden im Docker-Modus die Microservice-Architektur und die CI / CD-Praktiken endlich in die Tools nicht nur von DevOps-Ingenieuren, sondern auch von gewöhnlichen sterblichen Entwicklern aufgenommen. Um den Artikel interessanter zu gestalten, habe ich React.JS eine Front hinzugefügt, um die Bedürfnisse von mehr Personen abzudecken. Wenn Ihre Anwendung Encore nicht verwendet - es spielt keine Rolle, ich werde angeben, wie die Docker-Datei für Sie geändert werden soll. Die Unterstützung für React.JS wirkt sich nur darauf aus . Wer wird an diesem Tutorial interessiert sein? Zunächst richtet es sich an PHP-Entwickler, die ihre Bereitstellungspraxis ändern möchten - sich von den üblichen Kanonen entfernen und Docker verwenden, um ihre Anwendung zu packen und das Image zu erstellen. Sie können jedoch etwas tiefer gehen, und die weitere Beschreibung zielt darauf ab, die Anwendung automatisch von Git über die CI / CD-Plattform bereitzustellen (CircleCI wird verwendet, aber wenn Sie an der Gitlab-Konfiguration interessiert sind, schreiben Sie in die Kommentare, ich werde sie anhängen). Tatsächlich ist es für React / PHP absolut nicht wichtig, ob Sie eine Anwendung oder beispielsweise .NET Core haben. Dieser Teil ist für Entwickler interessant, um allgemein Fähigkeiten zur Bereitstellungsautomatisierung zu erwerben. Der Quellcode ist im Github-Repository verfügbar, Link am Ende des Artikels. Nun, lass uns gehen!

Ich gehe davon aus, dass Sie Ihre eigene Symfony-Anwendung haben, aber zu Demonstrationszwecken habe ich „Hallo Welt!“ Skizziert, die die folgenden Pakete enthält:

`symfony/webpack-encore-bundle symfony/form symfony/orm-pack symfony/profiler-pack symfony/security-bundle symfony/twig-bundle symfony/validator symfony/phpunit-bridge` ist ein minimaler Gentleman-Satz. Im Moment sollte die Ordnerstruktur wie folgt aussehen:

Bild

Jetzt müssen Sie Ihre Cloud-Infrastruktur konfigurieren. Ich werde mich nicht auf die Registrierung und Aktivierung des Testzeitraums von AWS konzentrieren. In dieser Phase müssen wir zwei DB-Instanzen erstellen. Ich werde zwei Arten von Umgebungen verwenden: STG (Staging), um die Implementierung neuer „Funktionen“ und PROD (Produktion) als direkten „Kampf“ zu testen. Server Es wurden viele Artikel über die Vorteile der Managed Service-Datenbank geschrieben. Darüber hinaus verfolgen wir in diesem Handbuch hauptsächlich die Bequemlichkeit für den Entwickler. Daher verwenden wir RDS, anstatt unseren eigenen separaten Datenbankserver zu erstellen. Als DBMS für dieses Beispiel habe ich PostgreSQL verwendet. Sie können eine beliebige auswählen, zum RDS-Dienst gehen und zwei Instanzen der benötigten Kapazität und des benötigten Volumens erstellen. Da die .env Datei in Symfony "out of the box" für uns verfügbar ist, verwenden wir sie beispielsweise für PROD. Für STG erstellen wir eine Kopie von .env.stg und ändern APP_ENV=dev in APP_ENV=stg in .env.stg und APP_ENV=dev on APP_ENV=prod in .env und geben Sie auch die .env für jede der erstellten Instanzen ein.

Großartig, ein Anfang wurde gemacht! Wie Sie wissen, werden Symfony-Abhängigkeiten über Composer installiert. Verwenden Sie zum Installieren die Datei composer.sh, die wir im Stammverzeichnis des Projekts ablegen:

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 


Dies ist eine Softwareinstallationsanleitung von Composer .

Erstellen Sie nun für jede Umgebung Ihre eigene Docker-Datei im Stammverzeichnis des Projekts:

Dockerfile.stg (Inszenierung)
 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 


und

Dockerfile (Produktion)
 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 


Dateien können "wie sie sind" verwendet werden, es werden keine Makros für Änderungen verwendet. Lassen Sie uns durch den Inhalt der Docker-Datei gehen, um die „magische“ Berührung zu zerstreuen. Als "Grundlage" verwenden wir das offizielle PHP 7.2.19-Image mit dem integrierten Apache-Webserver (Sie können jedes Ihrer Wahl verwenden, ein Bundle mit Nginx konfigurieren usw. In diesem Beispiel verwende ich meiner Meinung nach am häufigsten das oben genannte. bequem). Die Expose-Zeile ist für uns im Moment nicht wichtig, sie selbst macht nichts, wird aber in Zukunft von ElasticBeanstalk verwendet, das sie für die korrekte Bereitstellung benötigt. Die folgenden Konstruktionen verwenden PHP-optimierte Produktionseinstellungen, die vom Hersteller empfohlen werden. Aktivieren Sie mod_rewrite für Apache und erhöhen Sie den maximalen Speicher für ein PHP-Skript von 128 auf 256 MB, damit Composer ordnungsgemäß funktioniert. Als nächstes installieren wir die erforderlichen Anwendungen, PHP-Abhängigkeiten und Erweiterungen und konfigurieren sie sofort. Wir weisen den Ordner / var / www dem Arbeitsverzeichnis unserer Anwendung zu - der Quellcode unserer Anwendung wird dort kopiert. Da Apache standardmäßig / var / www als Einstiegspunkt für seinen Host verwendet und sich die Symfony-Indexdatei in / var / www / public befindet, ändern wir den Stamm des Apache-Dokuments mit der folgenden Konstruktion. Dann installieren wir Composer, NodeJS und Garn nacheinander (wenn Sie encore / react.js in Ihrer Anwendung nicht verwenden, benötigen Sie die letzten beiden Punkte nicht). Schließlich kopieren wir unseren Quellcode und beginnen mit der Installation von Abhängigkeiten über Composer für Symfony und Garn für react.js. Die Bedeutung einer separaten Docker-Datei für STG liegt in der vorletzten Anweisung für Docker - Kopieren von .env.stg nach .env, sodass die .env-Datei im STG-Image die für diese Umgebung relevanten Parameter enthält. Sie können das Image lokal (natürlich mit installiertem Docker) sammeln, ausführen und sicherstellen, dass die Anwendung funktioniert und für diese Arbeit nichts anderes benötigt:

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

für STG und

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

für PROD.
Wir können EC2 verwenden, ELB / ASG konfigurieren usw. oder ElasticBeanstalk verwenden, was aus praktischen Gründen nur ein Geschenk für uns ist. Gehen Sie zum Abschnitt ElasticBeanstalk und erstellen Sie eine neue Anwendung mit Namen und Beschreibung. Erstellen Sie dann zwei zuvor erwähnte Umgebungen: STG und PROD, erstellen Sie beide Umgebungen als Webserverumgebung, geben Sie "Docker" als Plattform an und belassen Sie die Beispielanwendung als Anwendungscode. Die Bereitstellung in ElasticBeanstalk erfolgt durch Hochladen von Projektdateien oder Anweisungen, normalerweise in einem Zip-Archiv. In unserem Fall sieht der Ablauf folgendermaßen aus: Wir erfassen das Docker-Image unserer Anwendung, laden es in das Repository und laden die Anweisung anstelle des Quellarchivs oder des Docker-Images, wodurch ElasticBeanstalk angewiesen wird, das Image vom Remote-Server zu übernehmen und bereitzustellen. Und das alles automatisch.

Beginnen wir mit der Erstellung eines Repositorys zum Speichern von Docker-Images. Es gibt 2 Möglichkeiten:

1 - Ihr Projekt ist privat, sein Code ist geschlossen und das Repository muss ebenfalls geschlossen sein. In diesem Fall führen Sie entweder irgendwo Ihr eigenes Bildregister oder verwenden eine private Cloud. AWS verfügt über ECR für diese Zwecke. Sie können dort ein Repository erstellen, aber niemand zwingt Sie dazu.

2 - Sie haben ein Open Source-Projekt und können Dockerhub verwenden.

In unserem Beispiel ist der Code offen, aber ich werde zeigen, wie geschlossene Repositorys verwendet werden. Nachdem Sie diesen Prozess verstanden haben, wird es nicht schwierig sein, ein Bild von Dockerhub aus zu verbinden. Als erstes müssen wir das Repository selbst erstellen. Danach erhalten Sie den eindeutigen URI. Die weitere Beschreibung wird für Dritte gelten (nicht für AWS ECR-Repositories und deren Integration), für ECR werde ich danach schreiben.

Nach dem Erstellen des Repositorys müssen wir uns bei diesem Dienst anmelden, und es gibt einen kleinen Trick ... Gehen Sie zu den Einstellungen Ihres lokal installierten Dockers und überprüfen Sie, ob Sie die Option zum Speichern von Kennwörtern im externen Speicher entfernt haben (für MacOS-Benutzer: „Docker-Anmeldungen sicher speichern in macOS Keychain ”), sonst ist die benötigte Konfigurationsdatei leer. Und so autorisieren wir im ausgewählten Dienst das Speichern der Register Ihrer Bilder:

 docker login -u LOGIN -p PASSWORD REGISTRY 

Nach erfolgreicher Authentifizierung wird die folgende Konstruktion in der Konfigurationsdatei ~ / .docker / config.json angezeigt:

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

Wenn es nicht angezeigt wird, überprüfen Sie die oben beschriebene Docker-Konfiguration erneut.

Jetzt ist alles bereit, um die Anweisungsdatei für ElasticBeanstalk - Dockerrun.aws.json vorzubereiten. Der Code lautet wie folgt:

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


Im Allgemeinen sieht die Anweisung folgendermaßen aus: Nachdem Sie sich mit dem Schlüssel von KEY_PATH im S3-Speicher BUCKET_ID angemeldet haben, laden Sie das Image, indem IMAGE_URL das gespeicherte überschreibt, und leiten Sie es durch Portieren von Port 80 an denselben Port im Container. Nun zu den verwendeten Konstanten:

BUCKET_ID ist der „Rucksack“, der im S3-Dienst automatisch für Sie erstellt wird. Er hat die Form von ElasticBeanstalk-REGION-HASH. Hier findet das System Servicedateien für Ihren ElasticBeanstalk, einschließlich Anwendungsdateien, die Sie über die Schaltfläche „Hochladen und Bereitstellen“ herunterladen.

KEY_PATH - Pfad zur Autorisierungsdatei zum Image-Repository. Ich verwende das Format APP_NAME / cr.json, dh im Ordner in BUCKET_ID unter dem Namen meiner Anwendung (ich erstelle, falls noch nicht). Ich stelle die Datei cr.json mit dem nach der Autorisierung erhaltenen Code in das Register Bilder vor Ort:

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

IMAGE_URL ist die eindeutige URI Ihres Bildregisters + Tag des Bildes selbst, hier sollte alles klar sein.

Jetzt können wir diese Datei als Version unserer Anwendung in ElasticBeanstalk herunterladen. Er ruft das angegebene Image auf und stellt es bereit.

Dieser Prozess muss noch automatisiert werden. Und um absolut interessant zu sein, werde ich die Abfolge der Schritte für den nächsten Ablauf implementieren: Für alle Commits NICHT im Master-Zweig wird das Image gesammelt und in der STG-Umgebung bereitgestellt. Wenn wir in den Master pushen oder besser, schließen Sie es und füllen Sie es mit einer Zusammenführungsanforderung Dann wird der Code auf PROD bereitgestellt. So erhalten wir in PROD einen aktuellen Assistenten, in dem alles in Ordnung sein sollte, und Verzweigungen zum Entwickeln und Testen von neuem Code in STG. Für diese Implementierung benötigen wir Anweisungen zum Hochladen nicht aktueller Bilder, zum Kopieren von Dockerrun.aws.json in Dockerrun.aws.stg.json und zum Umbenennen von Dockerrun.aws.json in Dockerrun.aws.prod.json (nur zur Vereinfachung).

Das einzige, was Dockerrun.aws.stg.json von Dockerrun.aws.prod.json unterscheidet, ist 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" } ] } 


Wie ich am Anfang des Artikels sagte, werde ich CircleCI als CI / CD verwenden, was nach meinen persönlichen Gefühlen schneller ist als GitlabCI, wenn ich die kostenlose SaaS-Version verwende. Free Travis würde dies tun, aber da es nicht mit privaten Git-Repositories funktioniert, habe ich keine spezielle Demo durchgeführt, damit es keine Enttäuschung gibt, wenn eine solche Gelegenheit benötigt wird. Ich überlasse die Einstellungen für das Projekt in CircleCI den Lesern, um sie selbst zu studieren. Ich gebe die für die Bereitstellung erforderlichen Anweisungen selbst. Im Stammverzeichnis unseres Projekts erstellen wir den Ordner .circleci in der Datei config.yml mit den folgenden Inhalten:

.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 

Ich habe den Flow selbst etwas früher gemalt. Hier wird er in yaml-Anweisungen für CircleCI übersetzt. Lassen Sie uns die Implementierung bestimmter Schritte durchgehen. Es ist wichtig zu beachten, dass für CI definierte Umgebungsvariablen vorhanden sind, die von ihm während der Arbeit verwendet werden:

CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD werden benötigt, um auf den Docker-Image-Speicher zuzugreifen - dasselbe, was wir in cr.json eingegeben haben, nur ohne base64

CI_REGISTRY / CI_REGISTRY_ID bilden eine eindeutige Bild-URL ohne Tag

AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY - die Namen sprechen für sich. Dies sind AWS-Gutschriften für den Benutzer, in dessen Auftrag CircleCI bereitgestellt wird. Gehen Sie zu AWS IAM und erstellen Sie einen Benutzer, fügen Sie ihn der Gruppe der Administratoren hinzu und gewähren Sie nur programmgesteuerten Zugriff. Denken Sie daran, dass AWS_SECRET_ACCESS_KEY nur einmal zum Anzeigen / Kopieren verfügbar ist. Nachdem Sie auf den Show-Link geklickt haben, wird er nicht mehr angezeigt.

Zurück zu den CircleCI-Konfigurationsschritten. Was ist die Magie? Checkout lädt den Quellcode aus dem Git-Zweig in das aktuelle Arbeitsverzeichnis. Dieser Vorgang wird bei jedem Job wiederholt. Während des Erstellungsprozesses melden wir uns nacheinander beim Repository an, sammeln den auf Dockerfile.stg basierenden Code unter dem Tag XXX: dev und senden ihn an das Repository. Build-Master macht dasselbe, nur für den Build wird die "normale" Docker-Datei unter dem Tag XXX: latest verwendet.

deploy-stg installiert die AWS EB-CLI und erstellt ein Berechtigungsprofil in der Datei ~ / .aws / config, das für die ordnungsgemäße Funktion der CLI erforderlich ist. Anschließend werden die Variablen für die CLI initialisiert. Sie müssen die von Ihnen ausgewählte Region, die Plattform und immer Docker und den Namen Ihrer Anwendung angeben. Als Nächstes kopieren wir den Inhalt von Dockerrun.aws.stg.json in die neue Datei Dockerrun.aws.json und geben unter Verwendung der spezifischen Umgebung und Region einen Befehl zum Bereitstellen unserer Anwendung unter Verwendung des erstellten Berechtigungsprofils. Standardmäßig wird aufgrund dieses Befehls der gesamte Code des überwachten Zweigs in einem Zip-Archiv gespeichert, das auf ElasticBeanstalk heruntergeladen und dort entpackt wird. Dieser Vorgang ist jedoch relativ teuer. Daher haben wir eine neue Datei Dockerrun.aws.json erstellt, die ausreicht, um die von uns erstellte Datei bereitzustellen Remote-Image, und wir müssen es tatsächlich nur hochladen. Erstellen Sie dazu eine .ebignore-Datei im Projektstamm:

.ebignore
 * !Dockerrun.aws.json 

Diese Datei verwendet die .gitignore-Syntax und ist .gitignore, jedoch nicht für die Git-CLI, sondern für die AWS EB-CLI. In dieser Datei fordere ich die CLI auf, alle Dateien außer Dockerrun.aws.json zu überspringen. Wenn Sie jetzt den Job "deploy-stg" in ElasticBeanstalk ausführen, wird nur die von uns erstellte Datei gesendet. deploy-prod macht dasselbe, kopiert nur den Inhalt der Datei Dockerrun.aws.prod.json nach Dockerrun.aws.json, und der letzte gibt die Arbeitssequenz im CircleCI-Format an (deploy-stg nach dem Build und deploy-prod nach dem Build -master) und auf welchen Zweigen die Daten suchen (ignorieren: - master und nur: - master).

Eine etwas andere Sache ist bei AWS ECR, wie ich versprochen habe, wir werden darauf zurückkommen. Sie müssen sich nicht remote bei der ECR anmelden und eine cr.json-Datei erstellen, da ElasticBeanstalk „einen Bruder persönlich kennt“. Dementsprechend wird Dockerrun.aws.json anders aussehen - es wird einfach keinen Authentifizierungsblock geben:

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


Aber wie erfolgt dann die Authentifizierung? Tatsache ist, dass der Dienst, der auf die ECR zugreift, bestimmte Rechte hat, die wiederum auf bestimmten Sicherheitsrichtlinien basieren. In unserem Fall wird beim Starten der Bereitstellung über die AWS-CLI von einem Drittanbieter-Server (von CI) die Rolle "aws-elasticbeanstalk-ec2-role" verwendet. Suchen Sie sie im AWS IAM im Abschnitt "Rollen" und fügen Sie die zusätzliche Richtlinie "AmazonEC2ContainerRegistryReadOnly" hinzu. Das Herunterladen von einem privaten Repository auf seinen „Nachbarn“ ist nun fehlerfrei erfolgreich.

Dies wird jedoch genau von derselben VPC geladen. Über die CLI ist der Docker-Anmeldebefehl auch nicht "ohne Tricks": Sie müssen Credits für die Docker-Anmeldung über die AWS-CLI erhalten (nur erhalten), dafür gibt es einen Befehl

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

Dieser Befehl gibt eine Zeile des Formular-Docker-Logins zurück ...

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

Der Befehl erhält zuerst eine Zeichenfolge zur Authentifizierung und startet dann den entsprechenden Prozess. In Anbetracht dieser Regeln für AWS ECR sieht die Anweisungsdatei für CircleCI folgendermaßen aus:

.circleci / config.yml (für 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 , . , :

Bild

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

GitHub: tutorial-aws-symfony-ci

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


All Articles