dkd logo

Das automatisierte Multistage-Deployment

In diesem Artikel werfen wir einen Blick auf das automatisierte Multistage-Deployment von SSR-Nuxt-Vue3-headless-CMS-Storyblok-Frontend-Applikationen via Gitlab-CI-Pipelines in die Cloudflare-Cloud mithilfe von Wrangler.

Multistage Deployment Nuxt

Herausforderung

Im Kontext von MACH-Headless-Architekturen, (eine Einführung zu MACH und Headless findest du hier in unserem Blog https://www.dkd.de/de/blog/mach-headless/) haben wir Frontend-Applikationen, welche die Daten von Headless-Systemen via API konsumieren.
Diese deployen wir automatisiert auf mehreren Stages in der Cloud, mit einem Nuxt-Storyblok-App-Gitlab-Deployment nach Cloudflare.

Unsere Frontend-Applikation ist eine Nuxt 3-SSR (Server Side Rendered)/*Vue 3-App* , welche via API-Daten aus dem headless-CMS (Content Management System) Storyblok lädt und rendert.

Die App wird via Gitlab-CI-Pipeline (CI steht für Continous Integration) gebuilded und per Wrangler in Worker bei Cloudflare deployed.

Unser Setup umfasst aktuell drei Stages:

  1. Development - git Branch "develop"- und "published"-Daten der Storyblock-API

  2. Staging - git Branch "main"- und "draft"-Daten der Storyblock-API

  3. Production - git Branch "main"- und "published"-Daten der Storyblock-API

Im folgenden wollen wir zeigen, wie wir dies technisch umgesetzt haben.

Nuxt 3-/Vue 3-Applikation

Unsere App basiert auf Nuxt 3-, Vue 3- und Tailwind-CSS für das Styling. Wir setzen auf SSR (Server Side Rendering), um die beste Performance und das beste SEO-Ergebnis zu erzielen.

Für den Zugriff auf die Storyblok-API benötigen wir ein Access Token, welches in der nuxt.config.ts gesetzt wird.

Damit dieses nicht hardcoded und somit unter anderem im Git landet und damit wir es für jede Stage ändern können, setzen wir dieses via Environment Variablen.

nuxt.config.ts

Verwendung der Module:

  • tailwindcss - für das Styling

  • i18n - für das Handling der Internationalisierung/Mehrsprachigkeit

  • storyblok - Für den Zugriff auf Storyblok, hier wird auch das Access Token via Environment-Variable gesetzt
    nuxt.config.ts Access Token

Die Environment-Variablen werden in den Gitlab CI-/CD-Settings für die unterschiedlichen Stages konfiguriert. Siehe Abschnitt Gitlab - Environment Variablen.

Cloudflare

Unsere App wird in die Cloud zu Cloudflare deployed. Sie laufen dort als Worker. Benötigt wird hierfür ein Cloudflare Account. Die Account-ID wird für das Deployment benötigt und von uns in den GitLab-Enviroment-Variablen des Projekts gespeichert.

Cloudflare Worker Overview

API Token

Genauso speichern wir das API Token. Dieses wird auch für das Deployment benötigt und kann im Cloudflare Dashboard angelegt werden.

Cloudflare API Token

Wrangler

Das Deployment zu Cloudflare verwendet Wrangler.

https://developers.cloudflare.com/workers/wrangler/
https://developers.cloudflare.com/workers/wrangler/ci-cd/

Gitlab CI Pipeline Konfiguration

Environment Variablen

Gitlab CI/CD VariablenIn den CI-/CD-Settings des Repos haben wir die erwähnten Environment-Variablen für die verschiedenen Stages angelegt. Sie stehen damit beim ausführen der Pipeline zur Verfügung.

.gitlab_ci.yml

Nachfolgend die .gitlab_ci.yml mit den drei Pipelines für die Stages: Develop, Staging und Production.

Die wichtigsten Schritte sind im Code dokumentiert:

# IMPORT This ci uses different env vars for the different stages
default:
  # Node docker ci worker image, could be alos something like this
  #  image: node:latestbuild:
  image: '$CI_REGISTRY/dkd/tools/gitlab/docker-ci-worker:node-16_php-8.1_ruby-2.7'

# Stage Develop
deploy_develop:
  stage: deploy
  environment: develop
  script:
    # Install dependencies 
    - yarn
    # Cloudflare specific app build
    - NITRO_PRESET=cloudflare yarn build
    # Deployment via wrangler
    # We dynamicaly set the name of the cloudflare worker by the current ci enviroment name
    - 'npx wrangler deploy .output/server/index.mjs --site .output/public --name dkd-nuxt-storyblok-$CI_ENVIRONMENT_NAME --compatibility-date 2022-11-30'
  artifacts:
    paths:
      - .output
  rules:
    # This pipeline will be excuted automatically if somebody push / merge something in the branch develop
    - if: '$CI_COMMIT_BRANCH == "develop"'

deploy_staging:
  stage: deploy
  environment: staging
  script:
    - yarn
    - NITRO_PRESET=cloudflare yarn build
    - 'npx wrangler deploy .output/server/index.mjs --site .output/public --name dkd-nuxt-storyblok-$CI_ENVIRONMENT_NAME --compatibility-date 2022-11-30'
  artifacts:
    paths:
      - .output
  rules:
     # This pipeline will triggered if somebody push / merge something in the branch main
     # the excution must be triggered manually in the gitlab interface
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual
    - if: '$CI_COMMIT_BRANCH != "main"'
      when: never

deploy_production:
  stage: deploy
  environment: production
  script:
    - yarn
    - NITRO_PRESET=cloudflare yarn build
    - 'npx wrangler deploy .output/server/index.mjs --site .output/public --name dkd-nuxt-storyblok-$CI_ENVIRONMENT_NAME --compatibility-date 2022-11-30'
  artifacts:
    paths:
      - .output
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual
    - if: '$CI_COMMIT_BRANCH != "main"'
      when: never

Fazit

Im Zusammenspiel mit Gitlab Pipelines und Cloudflare war es uns schnell möglich ein Multistage Deployment für unsere Storyblok Frontend Apps umzusetzen.