Docker: Node.js

Wie man eine Node.js-App mit Docker nutzt und bereitstellt

👋 Willkommen in der Stackhero-Dokumentation!

Stackhero bietet eine einsatzbereite Docker Cloud CaaS (Containers as a Service) Lösung, die zahlreiche Vorteile bietet, darunter:

  • Einfache Bereitstellung Ihrer Container in der Produktion mit nur einem docker-compose up.
  • Anpassbarer Domainname gesichert mit HTTPS (zum Beispiel, https://api.ihre-firma.com, https://www.ihre-firma.com, https://backoffice.ihre-firma.com).
  • Optimale Leistung und robuste Sicherheit durch eine private und dedizierte VM.
  • Mühelose Updates mit nur einem Klick.

Sparen Sie Zeit und vereinfachen Sie Ihr Leben: Es dauert nur 5 Minuten, um die Docker CaaS Cloud Hosting Lösung von Stackhero auszuprobieren und Ihre Container in der Produktion bereitzustellen!

Dieser Leitfaden bietet eine solide Grundlage für die Entwicklung einer Node.js-App und deren schnelle und einfache Bereitstellung in der Produktion.

Es sind keine Vorkenntnisse in Docker erforderlich. Alles ist so eingerichtet, dass ein reibungsloses Erlebnis gewährleistet ist; Sie benötigen lediglich Docker auf Ihrem Computer.

Diese Dokumentation ist sowohl für Anfänger als auch für erfahrene Benutzer konzipiert, die eine Node.js-Anwendung mit modernen, skalierbaren Technologien ohne unnötige Komplikationen bereitstellen möchten.

Die Hauptmerkmale dieser Lösung umfassen:

  • 💪 Einfache Einrichtung mit minimalem Aufwand
  • 🐳 Nutzung von Docker für Entwicklungs- und Produktionsumgebungen
  • 🔄 Automatisches Neuladen von Node.js bei Codeänderungen mit nodemon
  • 🚀 Bereitstellung in der Produktion mit einem einzigen Befehl
  • 🔒 TLS-Zertifikatsverwaltung für sichere HTTPS-Verschlüsselung
  • 🚧 Unterstützung für Staging- und Vorproduktionsplattformen
  • 🧱 Modulare und skalierbare Architektur

Falls Docker noch nicht auf Ihrem Computer installiert ist, können Sie es von der offiziellen Docker-Website herunterladen. Um zu überprüfen, ob Docker korrekt funktioniert, öffnen Sie ein Terminal und führen Sie docker version aus. Sie sollten Versionsinformationen ohne Fehler sehen.

Nach der Installation von Docker klonen Sie das folgende Boilerplate-Repository:

git clone https://github.com/stackhero-io/nodejsWithDockerGettingStarted/
cd nodejsWithDockerGettingStarted

Starten Sie dann die Entwicklungsplattform, indem Sie make development-start ausführen oder alle verfügbaren Befehle mit make help anzeigen.

Um die Entwicklungsplattform zu starten, führen Sie aus:

make development-start

Dieser Befehl erstellt das Docker-Image, führt es aus und startet das dev-Skript, das in my-app/package.json definiert ist (was dem Ausführen von npm run dev entspricht).

In diesem Beispiel wird eine einfache REST-API mit Express erstellt. Sie können die API anzeigen, indem Sie zu http://localhost:5000 navigieren. Die Seite sollte "Hello World" anzeigen.

Öffnen Sie als Nächstes die Datei my-app/src/app.js in Ihrem bevorzugten IDE und ändern Sie die folgende Zeile:

res.send('Hello World');

Ändern Sie sie zu:

res.send('Updated!');

Speichern Sie die Datei. Der Node.js-Code wird automatisch neu geladen und ein Aktualisieren von http://localhost:5000 zeigt die aktualisierte API-Antwort an.

Herzlichen Glückwunsch - Sie haben jetzt eine voll funktionsfähige Entwicklungsplattform!

Wenn Sie zusätzliche Pakete installieren müssen, können Sie make development-shell ausführen, um auf die Container-Shell zuzugreifen. Verwenden Sie innerhalb der Shell NPM mit npm install <package> oder Yarn mit yarn add <package>, um die gewünschten Pakete zu installieren.

Wenn Sie ein bestehendes Node.js-Projekt haben, das Sie mit Docker integrieren möchten, folgen Sie diesen Schritten:

  1. Erstellen Sie ein neues Verzeichnis namens my-app in Ihrem Projekt.

  2. Verschieben Sie alle Ihre Projektdateien in das Verzeichnis my-app, mit Ausnahme der Dateien .gitignore und .git.

  3. Kopieren Sie docker, secrets und Makefile aus dem Boilerplate in das Stammverzeichnis Ihres Projekts.

  4. Bearbeiten Sie die Datei .gitignore in Ihrem Projekt und fügen Sie die folgenden Zeilen hinzu:

    node_modules/
    secrets/*.production
    secrets/*.staging
    

Dieses Boilerplate geht davon aus, dass Ihre App auf Port 5000 hört. Wenn Sie einen anderen Port bevorzugen, können Sie die Datei docker/docker-compose.development.yml bearbeiten und die Umgebung mit make development-start neu starten.

Wenn Sie eine andere Node.js-Version angeben möchten, folgen Sie diesen Schritten:

  1. Öffnen Sie die Datei docker/my-app.dockerfile, die das Docker-Image für Ihre App definiert.
  2. Suchen Sie die erste Zeile, die FROM node:<version>-alpine liest.
  3. Ersetzen Sie <version> durch die gewünschte Node.js-Version. Es wird empfohlen, die Long-Term Support (LTS)-Version zu verwenden. Sie können die neueste LTS-Version auf der Node.js-Website überprüfen. Um beispielsweise die neueste LTS-Version (derzeit 22) zu verwenden, aktualisieren Sie die Zeile zu FROM node:22-alpine. Wenn Sie eine spezifische Versionsnummer bevorzugen, können Sie etwas wie FROM node:22.13.0-alpine verwenden.
  4. Speichern Sie Ihre Änderungen im Dockerfile.

Legen Sie Umgebungsvariablen für die Entwicklungsplattform in der Datei secrets/my-app.development fest.

Für die Produktion verwenden Sie die Datei secrets/my-app.production.

Übertragen Sie die Datei secrets/my-app.production nicht in Ihr Git-Repository! Diese Datei enthält sensible Informationen und wird standardmäßig im .gitignore des Boilerplates ignoriert, um versehentliches Teilen zu verhindern.

Wenn Ihre Node.js-App Dateien speichern muss (z. B. Benutzer-Uploads), sollten Sie einen Objektspeicherdienst wie MinIO in Betracht ziehen. Ein Objektspeicherdienst hilft Ihrer Anwendung, nahtlos zu skalieren und potenzielle Probleme zu reduzieren.

Wenn Sie Dateien lokal speichern möchten, stellen Sie sicher, dass Sie immer ein Docker-Volume verwenden. Das direkte Speichern von Dateien in einem Container kann zu Datenverlust führen. Dieses Boilerplate bietet ein Volume, das unter /persistent gemountet ist, um Dateien sicher zu speichern.

Speichern Sie niemals persistente Daten außerhalb des Verzeichnisses /persistent, es sei denn, Sie haben benutzerdefinierte Volumes erstellt und sind sich der Konfiguration sicher. Das Speichern von Dateien außerhalb von /persistent führt zu Datenverlust!

Sie können dieses Boilerplate leicht anpassen, um eine Staging-Umgebung hinzuzufügen. Gehen Sie dazu wie folgt vor:

  1. Erstellen Sie eine Kopie von docker/docker-compose.production.yml und benennen Sie sie in docker/docker-compose.staging.yml um. Diese Datei definiert die Container und die Konfiguration für Ihre Staging-Umgebung.
  2. Erstellen Sie die Datei secrets/my-app.staging, die alle für das Staging erforderlichen sensiblen Informationen enthält, wie z. B. Datenbankpasswörter oder API-Schlüssel.
  3. Suchen Sie im Makefile den Abschnitt "Staging platform" und heben Sie die Auskommentierung auf.

Führen Sie schließlich make help aus, um die neuen Staging-Befehle anzuzeigen, die jetzt verfügbar sind.

Wenn Sie noch keinen Stackhero for Docker-Dienst haben, können Sie einen einfach über Ihr Stackhero-Dashboard erstellen. Er wird innerhalb von etwa 2 Minuten aktiviert.

Wenn Sie neu bei Stackhero sind, können Sie das Docker-Container-Cloud-Hosting einen Monat lang kostenlos ausprobieren.

Bevor Sie Ihre App in der Produktion bereitstellen, müssen Sie einige Konfigurationsdateien vorbereiten:

  1. Kopieren Sie secrets/global.production.example nach secrets/global.production.
  2. Bearbeiten Sie secrets/global.production und ersetzen Sie <XXXXXX>.stackhero-network.com durch den Hostnamen Ihres Docker-Dienstes aus Ihrem Stackhero-Dashboard.
  3. Kopieren Sie secrets/my-app.production.example nach secrets/my-app.production.
  4. Bearbeiten Sie secrets/my-app.production und fügen Sie Ihre Anmeldeinformationen ein.
  5. Aktualisieren Sie docker/docker-compose.production.yml, indem Sie <XXXXXX>.stackhero-network.com durch den Hostnamen Ihres Docker-Dienstes ersetzen.

Die Bereitstellung in der Produktion ist einfach: führen Sie aus:

make production-deploy

Dieser Befehl erstellt einen Docker-Container, überträgt Ihre Projektdaten und sendet sie an Ihren Docker-Dienst in der Produktion. Öffnen Sie Ihren Browser und navigieren Sie zu Ihrem Docker-Dienst-Hostname (z. B. https://<XXXXXX>.stackhero-network.com). Sie sollten sehen, dass Ihre REST-API "Hello World" antwortet.

Sie können auch make production verwenden, das Ihre Container bereitstellt und Echtzeitprotokolle anzeigt.

Um Ihre Produktionsumgebung zu überwachen oder Probleme zu beheben, können Sie Ihre Protokolle mit diesen Befehlen anzeigen:

  • Um Live-Protokolle zu streamen, führen Sie aus: make production-logs-live
  • Um alle gespeicherten Protokolle abzurufen, führen Sie aus: make production-logs
  • Um Protokolle für einen bestimmten Tag abzurufen (ersetzen Sie YYYY-MM-DD durch das gewünschte Datum), führen Sie aus: make production-logs | grep "YYYY-MM-DD"

Wenn Sie einen anderen Domainnamen als https://<XXXXXX>.stackhero-network.com verwenden möchten, integriert Stackhero for Docker Traefik, um die Domainverwaltung zu vereinfachen. Traefik übernimmt das HTTP-Routing und die TLS-Verschlüsselung (HTTPS) für Sie.

Hier sind einige Beispiele, um Ihre Domainnamen anzupassen:

  • Um api.my-company.com über Ihren Container my-app auf Port 5000 mit TLS-Verschlüsselung bereitzustellen, aktualisieren Sie die Datei docker/docker-compose.production.yml, indem Sie den Abschnitt labels ersetzen mit:

        labels:
          - "traefik.enable=true" # Traefik aktivieren, um den Verkehr zu diesem Container zu leiten
          - "traefik.http.routers.my-app.rule=Host(`api.my-company.com`)" # Host definieren
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt" # Letsencrypt für TLS-Zertifikate verwenden
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # Port 5000 angeben
    
  • Um my-company.com über Ihren Container my-app auf Port 5000 bereitzustellen und alle Anfragen von www.my-company.com zu my-company.com umzuleiten, aktualisieren Sie den Abschnitt labels in derselben Datei mit:

        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.my-app.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Beide Domains einschließen
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # Port 5000 angeben
    
          # www.my-company.com zu my-company.com umleiten:
          - "traefik.http.routers.my-app.middlewares=redirect-www"
          - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
          - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
          - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
    

Vergessen Sie nicht, das DNS für my-company.com und www.my-company.com so zu konfigurieren, dass jeder als CNAME auf Ihren Docker-Dienst unter https://<XXXXXX>.stackhero-network.com zeigt.