Bearbeiten

CI/CD für eine serverlose Front-End-Anwendung in Azure

Azure Pipelines

Beim serverlosen Computing werden Server, Infrastruktur und Betriebssysteme abstrahiert, sodass sich Entwickler auf die Anwendungsentwicklung konzentrieren können. Eine robuste CI/CD (Continuous Integration/Continuous Delivery) dieser Anwendungen ermöglicht Unternehmen, vollständig getestete und integrierte Softwareversionen innerhalb von Minuten nach der Entwicklung zu liefern. Dies bildet das Rückgrat einer modernen DevOps-Umgebung.

Wofür steht CI/CD eigentlich?

  • Mit Continuous Integration können Entwicklungsteams Codeänderungen fast sofort in ein freigegebenes Repository integrieren. Diese Möglichkeit stellt in Verbindung mit dem automatischen Erstellen und Testen vor der Integration der Änderungen sicher, dass nur voll funktionsfähiger Anwendungscode für die Bereitstellung verfügbar ist.
  • Continuous Delivery ermöglicht, dass Änderungen an Quellcode, Konfiguration, Inhalt und anderen Artefakten so schnell und sicher wie möglich an die Produktion übermittelt und dem Endbenutzer bereitgestellt werden können. Der Prozess hält den Code jederzeit in einem bereitstellbaren Status. Ein Sonderfall davon ist Continuous Deployment, was die tatsächliche Bereitstellung für Endbenutzer einschließt.

In diesem Artikel wird eine CI/CD-Pipeline für das Web-Front-End einer serverlosen Referenzimplementierung erläutert. Diese Pipeline wird mithilfe von Azure-Diensten entwickelt. Das Web-Front-End veranschaulicht eine moderne Webanwendung mit clientseitigem JavaScript, wiederverwendbaren serverseitigen APIs und vorgefertigtem Markup, alternativ auch als Jamstack bezeichnet. Den Code finden Sie in diesem GitHub-Repository. In der Infodatei werden die Schritte zum Herunterladen, Erstellen und Bereitstellen der Anwendung beschrieben.

Das folgende Diagramm zeigt die in diesem Beispiel-Front-End verwendete CI/CD-Pipeline:

CI/CD-Pipeline in serverloser App unter Verwendung von Azure-Diensten

In diesem Artikel wird die Back-End-Bereitstellung nicht erörtert.

Voraussetzungen

Um mit dieser Beispielanwendung zu arbeiten, stellen Sie sicher, dass Sie über Folgendes verfügen:

  • Ein GitHub-Konto.
  • Ein Azure-Konto. Falls Sie noch kein Konto haben, können Sie ein kostenloses Azure-Konto ausprobieren.
  • Eine Azure DevOps-Organisation. Falls Sie keine haben, können Sie einen Basic-Plan ausprobieren, der DevOps-Dienste wie Azure Pipelines umfasst.

Verwenden eines Onlinesystems für die Versionskontrolle

Versionskontrollsysteme verfolgen Änderungen im Quellcode und steuern sie. Wenn Sie Ihren Quellcode mit einem Online-Versionskontrollsystem verwalten, können mehrere Entwicklungsteams zusammenarbeiten. Die Verwaltung ist auch einfacher als eine herkömmliche lokale Versionskontrolle. Diese Onlinesysteme können auch problemlos in führende CI/CD-Dienste integriert werden. Sie haben die Möglichkeit, den Quellcode zusammen mit Build- und Konfigurationsdateien in mehreren, zusammen als Repository bezeichneten Verzeichnissen zu erstellen und zu verwalten.

Die Projektdateien für diese Beispielanwendung befinden sich in GitHub. Wenn Sie kein GitHub-Konto haben, lesen Sie diese Dokumentation, um sich mit GitHub-Repositorys vertraut zu machen.

Automatisieren von Erstellung und Bereitstellung

Die Verwendung eines CI/CD-Diensts wie Azure Pipelines kann Sie beim Automatisieren der Erstellungs- und Bereitstellungsprozesse unterstützen. Sie können mehrere Phasen in der Pipeline erstellen, wobei jede Phase auf dem Ergebnis der vorherigen Phase basierend ausgeführt wird. Die Phasen können entweder in einem Windows- oder Linux-Container ausgeführt werden. Das Skript muss sicherstellen, dass die Tools und Umgebungen ordnungsgemäß im Container festgelegt werden. Azure Pipelines kann eine Vielzahl von Buildtools ausführen und mit einigen wenigen Online-Versionskontrollsystemen arbeiten.

Integrieren von Buildtools

Moderne Buildtools können den Buildprozess vereinfachen und bieten Funktionen wie Vorkonfiguration, Minimierung der JavaScript-Dateien und Generierung der statischen Website. Die Generatoren der statischen Website können Markupdateien erstellen, bevor sie den Hostservern bereitgestellt werden. Dies spart dem Benutzer Zeit. Sie können basierend auf dem Typ der Programmiersprache und der Plattform Ihrer Anwendung sowie der zusätzlichen erforderlichen Funktionen aus einer Vielzahl von Tools auswählen. Dieser Artikel enthält eine Liste beliebter Buildtools für eine moderne Anwendung.

Bei dem Beispiel handelt es sich um eine React-Anwendung, die mit Gatsby.js (Generator für statische Websites und Front-End-Entwicklungsframework) erstellt wurde. Diese Tools können während Entwicklungs- und Testphasen lokal ausgeführt und für die endgültige Bereitstellung dann in Azure Pipelines integriert werden.

Im Beispiel wird die Gatsby-Datei gatsby-ssr.js zum Rendern und gatsby-config.js für die Websitekonfiguration verwendet. Gatsby konvertiert alle JavaScript-Dateien im Unterverzeichnis pages des Ordners src in HTML-Dateien. Weitere Komponenten werden im components-Unterverzeichnis abgelegt. Im Beispiel wird auch das gatsby-plugin-typescript-Plug-In verwendet, das die Verwendung von TypeScript anstelle von JavaScript für Typsicherheit zulässt.

Weitere Informationen zum Einrichten eines Gatsby-Projekts finden Sie in der offiziellen Gatsby-Dokumentation.

Automatisieren von Builds

Das Automatisieren des Buildprozesses reduziert die menschlichen Fehler, die in manuellen Prozessen auftreten können. Die Datei azure-pipelines.yml enthält das Skript für eine zweistufige Automatisierung. In der Infodatei für dieses Projekt werden die Schritte beschrieben, die zum Einrichten der Automatisierungspipeline mithilfe von Azure Pipelines erforderlich sind. In den folgenden Unterabschnitten wird gezeigt, wie die Pipelinephasen konfiguriert werden.

Buildphase

Da Azure-Pipelines in das GitHub-Repository integriert ist, lösen Änderungen im nachverfolgten Verzeichnis des Mainbranchs die erste Phase der Pipeline aus, die Buildphase:

trigger:
  batch: true
  branches:
    include:
    - main
  paths:
    include:
    - src/ClientApp

Der folgende Codeausschnitt veranschaulicht den Beginn der Buildphase, wobei ein Ubuntu-Container zur Ausführung der Phase verwendet wird.

    stages:
    - stage: Build
      jobs:
      - job: WebsiteBuild
        displayName: Build Fabrikam Drone Status app
        pool:
          vmImage: 'Ubuntu-16.04'
        continueOnError: false
    steps:

Darauf folgen tasks und scripts, die zum erfolgreichen Erstellen des Projekts erforderlich sind. Dabei handelt es sich z. B. um:

  • Installieren von Node.js und Einrichten von Umgebungsvariablen,

  • Installieren und Ausführen von „Gatsby.js“, um die statische Website zu erstellen:

        - script: |
            cd src/ClientApp
            npm install
            npx gatsby build
          displayName: 'gatsby build'
    
  • Installieren und Ausführen des Komprimierungstools namens brotli, um vor der Bereitstellung die erstellten Dateien zu komprimieren:

        - script: |
            cd src/ClientApp/public
            sudo apt-get install brotli --install-suggests --no-install-recommends -q --assume-yes
            for f in $(find . -type f \( -iname '*.html' -o -iname '*.map' -o -iname '*.js' -o -iname '*.json' \)); do brotli $f -Z -j -f -v && mv ${f}.br $f; done
          displayName: 'enable compression at origin level'
    
  • Berechnen der Version des aktuellen Builds für die Cacheverwaltung,

  • Veröffentlichen der erstellten Dateien für die Verwendung in der Bereitstellungsphase:

        - task: PublishPipelineArtifact@1
          inputs:
            targetPath: 'src/ClientApp/public'
            artifactName: 'drop'
    

Nach erfolgreichem Abschluss der Buildphase wird die Ubuntu-Umgebung beseitigt und die Bereitstellungsphase in der Pipeline ausgelöst.

Bereitstellungsphase

Die Bereitstellungsphase wird in einem neuen Ubuntu-Container ausgeführt:

    - stage: Deploy
      jobs:
      - deployment: WebsiteDeploy
        displayName: Deploy Fabrikam Drone Status app
        pool:
          vmImage: 'Ubuntu-16.04'
        environment: 'fabrikamdronestatus-prod'
        strategy:
          runOnce:
            deploy:
              steps:

Diese Phase umfasst verschiedene Bereitstellungstasks und -skripts für Folgendes:

  • Herunterladen der Buildartefakte in den Container (dies geschieht automatisch, wenn PublishPipelineArtifact in der Buildphase verwendet wird),
  • Aufzeichnen der Buildreleaseversion und Aktualisieren im GitHub-Repository,
  • Hochladen der Websitedateien in Blob Storage, und zwar in einen neuen Ordner, der der neuen Version entspricht, und
  • Ändern des CDN, sodass auf diesen neuen Ordner verwiesen wird.

In den letzten beiden Schritten wird eine Cachelöschung repliziert, da die CDN-Edgeserver nicht mehr auf ältere Ordner zugreifen können. Der folgende Codeausschnitt zeigt, wie dies erreicht wird:

       - script: |
              az login --service-principal -u $(azureArmClientId) -p $(azureArmClientSecret) --tenant $(azureArmTenantId)
              # upload content to container versioned folder
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.html" --content-type "text/html"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.js" --content-type "application/javascript"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.js.map" --content-type "application/octet-stream"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --content-encoding br --pattern "*.json" --content-type "application/json"
              az storage blob upload-batch -s "$(Pipeline.Workspace)/drop" --destination "\$web\$(releaseSemVer)" --account-name $(azureStorageAccountName) --pattern "*.txt" --content-type "text/plain"
              # target new version
              az cdn endpoint update --resource-group $(azureResourceGroup) --profile-name $(azureCdnName) --name $(azureCdnName) --origin-path '/$(releaseSemVer)'
              AZURE_CDN_ENDPOINT_HOSTNAME=$(az cdn endpoint show --resource-group $(azureResourceGroup) --name $(azureCdnName) --profile-name $(azureCdnName) --query hostName -o tsv)
              echo "Azure CDN endpoint host ${AZURE_CDN_ENDPOINT_HOSTNAME}"
              echo '##vso[task.setvariable variable=azureCndEndpointHost]'$AZURE_CDN_ENDPOINT_HOSTNAME
            displayName: 'upload to Azure Storage static website hosting and purge Azure CDN endpoint'

Atomarische Bereitstellungen

Bei der atomarischen Bereitstellung wird sichergestellt, dass die Benutzer Ihrer Website oder Anwendung immer den Inhalt erhalten, der derselben Version entspricht.

In der CI/CD-Beispielpipeline werden die Websiteinhalte Blob Storage bereitgestellt, der als Ursprungsserver für das Azure CDN fungiert. Wenn die Dateien im Blobspeicher im selben Stammordner aktualisiert werden, wird die Website inkonsistent bedient. Das Hochladen in einen Ordner mit neuer Version, wie im vorherigen Abschnitt gezeigt, löst dieses Problem. Die Benutzer erhalten alles oder nichts vom neuen erfolgreichen Build, da das CDN nur dann auf den neuen Ordner als Ursprung verweist, nachdem alle Dateien erfolgreich aktualisiert wurden.

Versionierte Bereitstellung

Diese Vorgehensweise bietet folgende Vorteile:

  • Da neue Inhalte erst dann für Benutzer verfügbar sind, wenn das CDN auf den neuen Ursprungsordner verweist, führt dies zu einer atomarischen Bereitstellung.
  • Sie können bei Bedarf problemlos ein Rollback auf eine ältere Version der Website durchführen.
  • Da der Ursprung mehrere Versionen der Website parallel hosten kann, können Sie die Bereitstellung mithilfe von Techniken wie z. B. dem Zulassen der Vorschau für bestimmte Benutzer vor größerer Verfügbarkeit optimieren.

Hosten und Verteilen mithilfe der Cloud

Bei einem Content Delivery Network (CDN) handelt es sich um eine Gruppe verteilter Server, mit denen die Bereitstellung von Inhalten für Benutzer über einen großen geografischen Bereich hinweg beschleunigt wird. Jeder Benutzer erhält den Inhalt vom nächstgelegenen Server. Das CDN greift von einem Ursprungsserver aus auf diesen Inhalt zu und speichert ihn an strategischen Standorten auf Edgeservern zwischen. Für die Beispiel-CI/CD in diesem Artikel wird Azure CDN verwendet, wobei auf die Websiteinhalte verwiesen wird, die auf Azure Blob Storage als Ursprungsserver gehostet werden. Blob Storage ist für das Hosten der statischen Website konfiguriert. Eine Kurzanleitung zur Verwendung von Azure CDN mit Azure Blob Storage finden Sie unter Schnellstart: Integrieren eines Azure-Speicherkontos in CDN.

Im Folgenden finden Sie einige Strategien, die die CDN-Leistung verbessern können.

Komprimieren des Inhalts

Durch das Komprimieren der Dateien vor dem Einsatz wird die Dateiübertragungsgeschwindigkeit verbessert und die Seitenladeleistung für die Endbenutzer erhöht.

Hierfür gibt es zwei Möglichkeiten:

  1. Im Handumdrehen auf den CDN-Edgeservern. Dadurch wird die Bandbreitennutzung um einen erheblichen Prozentsatz verbessert, sodass die Website deutlich schneller ist als ohne Komprimierung. Es ist relativ einfach, diesen Komprimierungstyp für Azure CDN zu aktivieren. Da das Komprimierungstool vom CDN gesteuert wird, können Sie es nicht auswählen oder konfigurieren. Verwenden Sie diese Komprimierung, wenn die Leistung der Website kein wichtiger Faktor ist.

  2. Vorkomprimierung vor dem Erreichen des CDN, entweder auf dem Ursprungsserver oder vor dem Erreichen des Ursprungs. Durch die Vorkomprimierung wird die Runtimeleistung Ihrer Website weiter verbessert, da sie vor dem Abruf durch das CDN erfolgt. Die CI/CD-Pipeline im Beispiel komprimiert die erstellten Dateien in der Bereitstellungsphase mit brotli, wie im Buildabschnitt oben gezeigt. Die Verwendung der Vorkomprimierung bietet folgende Vorteile:

    1. Sie können ein beliebiges Komprimierungstool verwenden, mit dem Sie vertraut sind, und die Komprimierung genauer optimieren. Bei CDNs gibt es möglicherweise Beschränkungen hinsichtlich der verwendeten Tools.
    2. Einige CDNs beschränken Dateigrößen, die im Handumdrehen komprimiert werden können, was bei größeren Dateien zu einer Leistungsbeeinträchtigung führt. Bei der Vorkomprimierung werden keine Beschränkungen für die Dateigröße festgelegt.
    3. Die Vorkomprimierung in der Bereitstellungspipeline bewirkt, dass am Ursprung weniger Speicherplatz erforderlich ist.
    4. Dies ist schneller und effizienter als die CDN-Komprimierung.

Weitere Informationen finden Sie unter Verbessern der Leistung durch Komprimieren von Dateien in Azure CDN.

Beschleunigung dynamischer Websites

Die Verwendung von CDN eignet sich optimal für statische Inhalte, die auf den Edgeservern sicher zwischengespeichert werden können. Dynamische Websites erfordern jedoch, dass der Server Inhalte auf der Grundlage der Benutzerantwort generiert. Dieser Inhaltstyp kann nicht auf dem Edge zwischengespeichert werden. Dies erfordert eine komplexere End-to-End-Lösung, mit der die Inhaltsübermittlung beschleunigt werden kann. Die Beschleunigung dynamischer Websites durch Azure CDN ist eine Lösung, die die Leistung dynamischer Webseiten messbar steigert.

Dieses Beispiel ermöglicht die Beschleunigung dynamischer Websites, wie in diesem Abschnitt der Infodatei gezeigt.

Verwalten des Websitecaches

CDNs verwenden das Zwischenspeichern, um die Leistung zu verbessern. Das Konfigurieren und Verwalten dieses Caches wird zu einem integralen Bestandteil ihrer Bereitstellungspipeline. In der Azure CDN-Dokumentation werden verschiedene Möglichkeiten hierzu veranschaulicht. Sie können Zwischenspeicherungsregeln für Ihr CDN festlegen und die Gültigkeitsdauer für den Inhalt auf dem Ursprungsserver konfigurieren. Statische Webinhalte können über einen längeren Zeitraum zwischengespeichert werden, da sie sich im Laufe der Zeit nicht zu sehr ändern können. Dies reduziert den Mehraufwand für den Zugriff auf den einzelnen Ursprungsserver für jede Benutzeranforderung. Weitere Informationen finden Sie unter Funktionsweise der Zwischenspeicherung.

Cachebereinigung

Das CDN speichert die Websitedateien auf den Edgeservern zwischen, bis deren Gültigkeitsdauer abläuft. Diese werden erst für eine neue Clientanforderung aktualisiert, nachdem ihre Gültigkeitsdauer abgelaufen ist. Das Löschen des CDN-Caches ist erforderlich, um sicherzustellen, dass jeder Benutzer die neuesten Live-Websitedateien erhält. Dies gilt insbesondere, wenn die Bereitstellung im gleichen CDN-Ursprungsordner erfolgt. Azure CDN ermöglicht Ihnen, den Cache vom Azure-Portal aus zu löschen.

Ein besserer Ansatz ist, diesen Cache mithilfe der Versionsverwaltung während der Bereitstellung ungültig zu machen. Eine explizite Cachelöschung oder ein Ablauf bewirkt im Allgemeinen, dass das CDN neuere Versionen des Webinhalts abruft. Da das CDN jedoch immer auf die neueste Version der Bereitstellung verweist, wird das Zwischenspeichern wie folgt verbessert:

  1. Das CDN überprüft die Datei „index.html“ anhand des Ursprungs für jede neue Websiteinstanz.
  2. Alle Websitedateien mit Ausnahme der Dateien „index.html“ und „404.html“ werden mit einem digitalen Fingerabdruck versehen und für ein Jahr zwischengespeichert. Dies basiert auf der Annahme, dass Ressourcen wie Bilder und Videos nicht häufig geändert werden müssen. Wenn diese Dateien aktualisiert und neu erstellt werden, werden ihre Namen durch eine neue Fingerabdruck-GUID aktualisiert. Dies führt zu einem Update der Datei „index.html“ mit einem aktualisierten Verweis auf die geänderte Ressourcendatei. Das CDN ruft dann die aktualisierte Datei „index.html“ ab, und da die Verweisressourcendatei nicht in seinem Cache gefunden wird, werden auch die geänderten Ressourcendateien abgerufen.

Dadurch wird sichergestellt, dass das CDN immer neue aktualisierte Dateien erhält, und der Cache muss nicht mehr für einen neuen Build gelöscht werden.

Beitragende

Dieser Artikel wird von Microsoft gepflegt. Er wurde ursprünglich von folgenden Mitwirkenden geschrieben:

Hauptautor:

Melden Sie sich bei LinkedIn an, um nicht öffentliche LinkedIn-Profile anzuzeigen.

Nächste Schritte