CI/CD in Plesk: Node.js, React, Angular, Vue & Co. automatisch deployen

Mit Plesk CI/CD kann man Node.js, React, Angular, Vue und andere Technologien automatisch auf dem Server bereitstellen. In diesem Artikel zeige ich dir, wie Plesk CI/CD genutzt werden kann, um Deployment-Prozesse zu automatisieren und die Entwicklungszeit zu verkürzen.

Beim Entwickeln von Fullstack Anwendungen mit Node.js, Deno und Frontend Frameworks wie Vue, React oder Angular ist der Deyploment-Prozess, also der Schritt in dem die entwickelte Anwendung live gestellt wird immer ähnlich. Diese Arbeiten manuell durchzuführen benötigt sehr viel Zeit und ist bei manueller Bearbeitung auch sehr fehleranfällig. Und genau hier kommt CI/CD zum Einsatz.

Was dich in diesem Tutorial erwartet:
Wir bauen eine komplette Plesk CI/CD Pipeline. Lokale Änderungen commitest du auf deinen develop Branch im Remote Respository und erstellst einen Pull Request (PR) auf deinen main Branch. Deine App wird automatisch getestet und dein Quellcode formatiert (linting) und bei Erfolg alles auf deinem main Branch gepusht. Das Frontend wird dann automatisch gebuilded. Plesk erkennt diese Änderungen und stellt alle Änderungen automatisch für deine Nutzer bereit. Du kannst diesen Workflow aber auch für statische Webseiten nutzen.

Plesk CI/CD Pipeline visualisiert
Plesk CI/CD Pipeline visualisiert

Dieses Diagramm soll visualisieren, wie die komplette Plesk CI/CD Pipeline mit samt allen Schritten aussieht. Nimm dir einen Moment Zeit und schaue dir die einzelnen Schritte genau an.

Was ist CI/CD?

CI/CD steht für Continous Integration/Continous Delivery und beschreibt eine Methode der kontinuierlichen Integration und Bereitstellung von Änderungen an einer Software. Dies ermöglicht es Entwicklern, schnell und effizient zu iterieren, ohne auf manuelle Prozesse angewiesen zu sein. Im Rahmen einer CI/CD Pipeline werden verschiedene Prozesse automatisiert ausgeführt, wie zum Beispiel das Zusammenführen von Code-Änderungen, das Kompilieren und Testen der Anwendung sowie das automatische Deployment auf Server.

Plesk CI/CD ist eine integrierte Lösung auf der Server-Management-Plattform Plesk, die es Entwicklern ermöglicht, ihre Anwendungen nahtlos auf dem Server bereitzustellen. Dabei können unterschiedliche Technologien wie Node.js, React, Angular, Vue und weitere verwendet werden. Plesk CI/CD unterstützt die gängigen Versionierungstools wie Git, Subversion und Bitbucket. Außerdem bietet es eine benutzerfreundliche Oberfläche, mit der Entwickler ihre CI/CD Pipeline einrichten und konfigurieren können.

Mit Plesk CI/CD können Entwickler Zeit und Aufwand sparen, indem sie ihre Deployment-Prozesse automatisieren und beschleunigen. Dadurch wird die Entwicklungszeit verkürzt und die Software kann schneller und effizienter bereitgestellt werden.

Voraussetzungen/Annahmen

Zu Beginn treffe ich ein paar Annahmen über die App, nach der die Pipeline entwickelt wird. Es ist aber natürlich nicht schlimm, wenn du andere Voraussetzungen hast, an ein paar Stellen musst du deine Plesk CI/CD Pipeline dann anpassen.

  • Backend und Frontend sind in getrennten Repositories (am besten GitHub, da ich hier GitHub Actions nutze)
  • Das Frontend ist mit einem JS Framework erstellt (z.B. Vue, React oder Angular). Dementsprechend kommt npm oder yarn zum Einsatz
  • Das Backend ist eine Node.js Anwendung
  • Die Plesk Git extension muss in deinem Plesk installiert sein (per Klick unter Erweiterungen > „Git“)

GitHub Actions: CI/CD Workflows erstellen

Mit GitHub Actions können wir verschiedene Workflows erstellen, die jeweils eine spezielle Aufgabe in unserer CI/CD Pipeline übernehmen. Einen neuen Workflow legst du wie folgt an.

GitHub Actions: CI/CD Workflow erstellen
GitHub Actions: CI/CD Workflow erstellen

Du erhältst diesen Editor, der eine Datei im YAML Format bereitstellt.

GitHub Actions: Node.js Workflow Editor
GitHub Actions: Node.js Workflow Editor

Hier erstellen wir jetzt verschiedene YAML-Dateien für die einzelnen Steps in unserer Pipeline.

Unit Tests ausführen

Wenn du für deinen Code Unit Tests angelegt hast, z.B. mit Mocha oder supertest, kannst du die folgende YAML-Datei verwenden. Enthält dein Code keine Tests, kann ich dir nur dringend empfehlen welche zu erstellen. In einem anderen Artikel habe ich bereits gezeigt, wie du mit ChatGPT Unit Tests generieren lassen kannst oder mithilfe von Postman deine Rest API testen kannst.

name: Execute Unit Tests

on:
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]

    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
        
    - name: Install dependencies and run tests
      run: |
        npm install
        npm run test
      env:
        CI: true # set environment variable to run tests in CI mode

Diese Datei habe ich testing.yml benannt. Sie wird ausgeführt, wenn ein Commit auf dem develop Branch ankommt oder ein Pull Request auf dem main Branch angelegt wird. Sie lädt zuerst den aktuellen Code aus dem Repo, installiert dann alle Dependencies und führt dann npm run test aus. In deiner package.json muss natürlich auch das entsprechende Skript hinterlegt sein. So sieht der Abschnitt in der package.json aus, wenn du Mocha als Test-Framework verwendest und deine Tests im test/ Ordner liegen:

{
  [...]
  "scripts": {
    [...]
    "test": "mocha test/**/*.test.js",
    [...]
  },
  [...]
}

Linting/Formatting ausführen

Ich kann außerdem nur dringend dazu raten, einen Linter bzw. Formatter für dein Projekt aufzusetzen. Dieser prüft und korrigiert automatisch die Code Formatierung. Besonders bei der Arbeit mit mehreren Entwicklern ist das ein großer Vorteil, um die Code Qualität zu gewährleisten. Die YAML-Datei für GitHub Actions kann so aussehen:

name: Execute Linting
on:
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]

    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
        
    - name: Install dependencies and lint code
      run: |
        npm install
        npm run lint
      env:
        CI: true # set environment variable to run tests in CI mode

Und in der package.json muss wieder das entsprechende Skript hinterlegt sein. Hier als Beispiel bei der Nutzung von eslint.

{
  [...]
  "scripts": {
    [...]
    "lint": "./node_modules/.bin/eslint .",
    [...]
  },
  [...]
}

Frontend bauen

Wenn wir lokal entwickeln starten wir immer einen Entwicklungsserver auf unserem Rechner. Für den Livegang (Production) müssen wir einen Befehl wie npm run build oder ähnliches ausführen. Diesen Prozess wollen wir jetzt automatisieren.

Mit der folgenden Vorlage werden mehrere Jobs ausgeführt. Die Dependencies werden installiert, der Code wird wieder gelintet und das Frontend wird gebaut. Optional kannst du hier wieder die Ausführung von Unit Tests ergänzen.

Im letzten Schritt pushen wir den kompletten Build auf den Branch build des gleichen Repositories. Vermutlich musst die markierte Zeile anpassen. Hier gibst du den Namen des Ordners an, in dem dein Frontend gebaut wurde. Bei Vue.js ist das standardmäßig der dist/ Ordner. Bei React ist das meist der public/APPNAME/ Ordner. Der Pfad kann aber auch über die Config des jeweiligen JS Frameworks angepasst werden.

name: Build Application

on:
  push:
    branches: [ "main" ]

jobs:
  test-and-build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]

    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
        
    - name: Install dependencies
      run: |
        npm ci
        
    - name: Lint code
      run: |
        npm run lint
      env:
        CI: true # set environment variable to run tests in CI mode
        
    - name: Build Frontend
      run: npm run build
      env:
       CI: false
    
    - name: Push to build branch
      uses: s0/git-publish-subdir-action@develop
      env:
        REPO: self
        BRANCH: build # The branch name where you want to push the assets
        FOLDER: ./dist # The directory where your assets are generated
        GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} # GitHub will automatically add this - you don't need to bother getting a token
        MESSAGE: "Build: ({sha}) {msg}" # The commit message

Sobald du die Workflow Datei abspeicherst wird der Job automatisch ausgeführt und dein Frontend gebaut und auf den build Branch gepusht. Das kann je nach Frontend auch mal 1-2 Minuten dauern.

GitHub Workflow ausführen
GitHub Workflow ausführen

Git Repository in Plesk einrichten

Im nächsten Schritt müssen wir unsere beiden Git Repositories in Plesk einrichten. Für Frontend und Backend richten wir jeweils eine unterschiedliche Bereitstellung aus.

Git Repositories für Plesk CI/CD Workflow
Git Repositories für Plesk CI/CD Workflow

Backend

Wähle für das Backend Repository folgende Einstellungen aus:

  • Nutze die SSH Repository URL deines Backends (git@github.com:USERNAME/REPO.git)
  • Branch: main
  • Bereitstellungsmodus: automatisch
  • Serverpfad: /httpdocs
  • Bereitstellungsaktionen (um nicht benötigte Dateien direkt zu löschen):
    • touch tmp/restart.txt
    • rm -R .github/
    • rm .env.template
    • rm -R test/
    • rm README.md
    • rm .gitignore
    • rm .eslintrc.js

Alles Infos zum Hosting einer Node Anwendung erfährst du in meinem ausführlichen Beitrag zum Thema Node.js App Hosting mit Plesk.

Frontend

Die zweite Repo-Instanz in Plesk ist nur fürs Frontend. Wählen hier folgende Einstellungen aus:

  • Nutze die SSH Repository URL deines Frontends (git@github.com:USERNAME/REPO.git)
  • Branch: build (falls dieser noch nicht existiert, erstelle ihn, den benötigen wir später)
  • Serverpfad: /httpdocs/public
  • Bereitsstellungsmodus: automatisch

Das Anzeigen des Frontends machen wir über unser Backend. Dazu müssen in der index.js der Node.js App folgende Zeilen ergänzt werden:

// handle production
if (process.env.NODE_ENV === "production") {
  // static folder
  app.use(express.static(__dirname + "/public"));

  // handle SPA
  app.get(/.*/, (req, res) => res.sendFile(__dirname + "/public/index.html"));
}

Ich habe ein Node.js Backend mit express Webserver. Nutzt du andere Technologien, kannst du das entsprechend umschreiben lassen.

Bis hierher werden unsere Dateien bereitgestellt, wenn wir den Pull manuell in Plesk ausführen. Wenn wir also lokal einen Commit machen und ihn in unser Remote Repository pushen müssten wir uns immer in Plesk anmelden und den „Jetzt Pull ausführen“ Button klicken. Diese Automatisierungen konfigurieren wir im nächsten Schritt.

Plesk Git SSH-Key in GitHub einrichten

Zuvor müssen wir aber Plesk noch erlauben auf unser privates GitHub Repository zuzugreifen. Dazu müssen wir den von Plesk erstellten öffentlichen SSH-Schlüssel kopieren.

Plesk SSH-Schlüssel für GitHub kopieren
Plesk SSH-Schlüssel für GitHub kopieren

Diesen Schlüssel musst du in deinem GitHub Account unter Settings > SSH and GPG Keys > New SSH key einfügen.

Eine ausführliche Anleitung zu diesem Schritt findest du in meinem Beitrag privates GitHub Repository mit Plesk klonen.

Webhooks: Automatisches Abrufen neuer Commits

Was haben wir bisher: Frontend und Backend werden jetzt in den richtigen Verzeichnissen auf unserem Plesk Server gehostet und unser Frontend wird automatisch mit GitHub Actions gebaut. Für einen kompletten Plesk CI/CD Workflow fehlt nur noch, dass neue Commits automatisch von Plesk erkannt werden und bereit gestellt werden. Dazu nutzen wir Webhooks.

In den Repository Einstellungen in Plesk findest du eine Webhook-URL, die du dir rauskopieren musst.

Plesk Git Repository: Webhook-URL auslesen
Plesk Git Repository: Webhook-URL auslesen

Anschließend gehst du in die Repository Einstellungen in deinem GitHub Repo unter Settings > Webooks und klickst auf Add webhook. Hier fügst du die URL ein und lässt alle anderen Einstellungen auf ihren Standardwerten.

GitHub: Webhooks hinzufügen
GitHub: Webhooks hinzufügen

Sollte dein Workflow nicht funktionieren und Fehlermeldungen mit fehlenden Berechtigungen erscheinen, musst du eventuell unter GitHub Settings > Developer seettings > Personal access tokens > Tokens (classic) einen neuen Token generieren und alle Berechtigungen auf „repo“ erlauben.

Das war’s! Alle Bestandteile unsere Plesk CI/CD Pipeline stehen und sind funktionsfähig.

Das Aufsetzen des Workflows hat sicherlich etwas Zeit in Anspruch genommen, dafür spart es in Zukunft sehr viel Zeit ein. 🙂

Ähnliche Beiträge
Beteilige dich an der Unterhaltung

2 Kommentare

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

bold italic underline strikeThrough
insertOrderedList insertUnorderedList outdent indent
removeFormat
createLink unlink
code

Das könnte dich auch interessieren