tva
← Insights

React-Deployment 2026: Unveränderliche Builds, Traefik und Releases ohne Ausfallzeit

Ein aktueller, auf den Produktivbetrieb ausgerichteter Folgebeitrag, der Herstellerempfehlungen in betriebliche Kontrollmaßnahmen, Migrationsentscheidungen und überprüfbare Freigabekriterien übersetzt.

Was sich 2026 geändert hat

Wir greifen das Thema erneut auf, weil sich die Systemgrenzen verschoben haben. Die dauerhaften Prinzipien bleiben wertvoll, doch aktuelle Versionen machen einige frühere Abkürzungen unvollständig oder riskant. Dieser Folgebeitrag beginnt mit der am 14. Juli 2026 verfügbaren Herstellerdokumentation, trennt Fakten von lokalen Entscheidungen und behandelt jede Konfigurationsänderung als kontrollierten Eingriff in den Produktivbetrieb.

Aktuelle Primärquellen

So setzen wir die Aktualisierung ein

Zuerst werden die Primärquellen geprüft und die tatsächlich eingesetzten Versionen dokumentiert. Vor jeder Änderung definieren wir das beobachtbare Ergebnis. Der kleinste reversible Eingriff wird in einer repräsentativen Umgebung getestet. Ein erfolgreicher Befehl ist noch kein Abnahmekriterium: Entscheidend sind Dienstzustand, Datenintegrität, Latenz, Sicherheitsgrenzen und Rücksetzzeit. Die weiterhin nützliche Diagnoselogik des früheren Beitrags bleibt nachfolgend als betriebliche Grundlage erhalten; versionsabhängige Beispiele müssen mit der aktuellen Dokumentation abgeglichen werden. Die nachfolgend genannten Konfigurationsdateien und Befehle finden Sie in der ursprünglichen Anleitung.

Betriebliche Grundlage

Eine React-Anwendung lokal zu erstellen ist unkompliziert. Sie korrekt auf Produktivservern bereitzustellen? Genau hier stoßen die meisten Entwickler auf unerwartete Hindernisse. Dieser Leitfaden dokumentiert eine reale Debugging-Sitzung bei der Bereitstellung, bei der alles korrekt konfiguriert schien – Container lief, Traefik-Labels gesetzt, DNS aufgelöst – und dennoch gab die Anwendung hartnäckige 404-Fehler zurück.

Heute führen wir Sie durch den gesamten Prozess des lokalen Erstellens von React-Anwendungen und deren Bereitstellung auf Docker-Servern im Produktivbetrieb mit korrekter Reverse-Proxy-Konfiguration, automatischem SSL und professionellem Domain-Routing. Dieser Ansatz baut auf unserer Philosophie selbst betriebener Lösungen auf – ähnlich wie wir gezeigt haben, dass Sie n8n für Workflow-Automatisierung selbst hosten und mandantenfähige Entwicklungsstacks aufbauen können, um die vollständige operative Kontrolle zu behalten.

Das Problem mit herkömmlichen React-Bereitstellungen

Die meisten React-Bereitstellungs-Tutorials überspringen die kritischen Details für den Produktivbetrieb. Sie finden Anleitungen, die npm run build und das Kopieren von Dateien nach nginx zeigen, aber sie behandeln selten:

Konfigurationskonflikte:

  • Benutzerdefinierte HTTP-Router, die globale Weiterleitungen überschreiben
  • Traefik-Label-Syntaxfehler, die zu stillen Fehlern führen
  • IPv6- vs. IPv4-Bindungsprobleme bei Health Checks
  • Fehlende Service-Port-Zuordnungen, die 404-Fehler erzeugen

Ressourcenverwaltung:

  • Fehler wegen voller Festplatte, die die Container-Registrierung verhindern
  • Aufgeblähte Docker-Images durch unnötige Build-Artefakte
  • Ineffiziente Caching-Strategien, die Bereitstellungen verlangsamen
  • Speicherbeschränkungen, die die Build-Leistung beeinträchtigen

Eignung für den Produktivbetrieb:

  • Ordnungsgemäße SSL-Zertifikatsautomatisierung
  • Bereitstellungsstrategien ohne Ausfallzeit
  • Health-Check-Konfigurationen

Das Ergebnis? Stunden vergehen bei der Fehlersuche, weil eine lokal einwandfrei funktionierende App im Produktivbetrieb mysteriöse 404-Fehler zurückgibt, obwohl „alles korrekt aussieht“.

Die von uns verwendeten Tools

Betrachten wir, was jede Komponente in unserer schlanken React-Bereitstellungsarchitektur leistet:

Vite: Modernes Build-Tool

Vite bietet blitzschnelle Entwicklung und optimierte Builds für den Produktivbetrieb. Im Gegensatz zu Create React App nutzt Vite native ES-Module während der Entwicklung und erstellt hochoptimierte Bundles für den Produktivbetrieb. Ihre React-App wird in Sekunden statt Minuten gebaut.

Der entscheidende Vorteil? Vite übernimmt automatisch Code-Splitting, Tree Shaking und Asset-Optimierung. Sie erhalten für den Produktivbetrieb geeignete Builds ohne komplexe Webpack-Konfigurationen.

Docker: Containerisierung für Konsistenz

Docker stellt sicher, dass Ihre React-App in der Entwicklung und im Produktivbetrieb identisch läuft. Derselbe nginx-Container, der Ihre App lokal bereitstellt, verhält sich auf Ihrem Produktivserver exakt gleich – das klassische „funktioniert auf meinem Rechner“-Problem wird eliminiert.

Stellen Sie sich Docker als Verpackung Ihrer gesamten Anwendungsumgebung (React-Build-Dateien, nginx-Konfiguration und Laufzeitumgebung) in einen portablen Container vor, der überall funktioniert.

Traefik: Intelligenter Reverse Proxy

Traefik fungiert als intelligenter Verkehrsleiter, der Anfragen automatisch basierend auf Domainnamen an die korrekten containerisierten Anwendungen weiterleitet. Anstatt manuell komplexe nginx- oder Apache-Regeln für jede neue Anwendung zu konfigurieren, liest Traefik Labels aus Ihren Docker-Containern und richtet das Routing automatisch ein.

In unserem mandantenfähigen Docker-Setup haben wir die Leistungsfähigkeit von Traefik für die Verwaltung mehrerer Kundenumgebungen demonstriert. Dieselben Prinzipien gelten hier für die Verwaltung mehrerer React-Anwendungen auf einem einzigen Server.

Traefik übernimmt automatisch die SSL-Terminierung über Let's Encrypt, erkennt Dienste automatisch und ermöglicht detailliertes Monitoring – alles mit minimaler Konfiguration.

nginx: Webserver für den Produktivbetrieb

nginx stellt Ihre statischen React-Build-Dateien mit außergewöhnlicher Leistung bereit. Es ist der De-facto-Standard für die Bereitstellung statischer Inhalte im Produktivbetrieb und verarbeitet effizient Tausende gleichzeitiger Verbindungen bei minimalem Ressourcenverbrauch.

Den Bereitstellungsablauf verstehen

Hier ist der vollständige Weg von der lokalen Entwicklung zum Produktivbetrieb:

  • Lokale Entwicklung: Erstellen und testen Sie Ihre React-App mit npm run dev
  • Build für den Produktivbetrieb: Erstellen Sie optimierte statische Dateien mit npm run build
  • Containerisierung: Verpacken Sie Build-Dateien in einen nginx-Docker-Container
  • Server-Bereitstellung: Hochladen und Starten des Containers auf dem Produktivserver
  • Traefik-Registrierung: Automatisches Routing und SSL-Zertifikatsbereitstellung
  • Zustandsüberwachung: Kontinuierliche Health Checks stellen die Verfügbarkeit sicher

Was dies so leistungsfähig macht, ist die Automatisierung. Einmal korrekt konfiguriert, können Sie Updates in unter 60 Sekunden mit einem einzigen Befehl bereitstellen.

Einrichtung Ihrer React-Anwendung

Projektstruktur für den Produktivbetrieb

Organisieren Sie Ihr React-Projekt mit Blick auf die Bereitstellung:

my-react-app/
├── src/                    # React source code
├── public/                 # Static assets
├── dist/                   # Build output (auto-generated)
├── package.json            # Dependencies
├── package-lock.json       # Locked dependency versions (npm ci)
├── vite.config.ts          # Vite configuration
├── Dockerfile              # Container definition
├── nginx.conf              # nginx configuration
└── docker-compose.yml      # Deployment definition

Optimierung Ihrer Vite-Konfiguration

Erstellen Sie vite.config.ts mit für den Produktivbetrieb optimierten Einstellungen:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  build: {
    outDir: 'dist',
    sourcemap: false, // Do not publish source maps in production
    // Minification is on by default (Oxc minifier in Vite 8)
    rolldownOptions: {
      output: {
        // Vite 8 (Rolldown): codeSplitting replaces the manualChunks object form
        codeSplitting: {
          groups: [
            { test: /node_modules[\\/](react|react-dom|scheduler)[\\/]/, name: 'vendor' },
          ],
        },
      },
    },
  },
  server: {
    port: 3000,
    host: true, // Enable network access
  },
})

Diese Konfiguration:

  • Trennt Vendor-Bibliotheken für besseres Caching
  • Minifiziert Code für kleinere Dateigrößen
  • Deaktiviert Source Maps im Produktivbetrieb (verhindert Code-Offenlegung)
  • Optimiert Chunk-Splitting für schnellere Ladezeiten

Build für den Produktivbetrieb

Erstellen Sie Ihr optimiertes Bundle für den Produktivbetrieb:

# Install the exact dependency versions from package-lock.json
npm ci
# Create production build
npm run build
# Verify build output
ls -lh dist/

Ihr dist/-Ordner sollte enthalten:

  • index.html – Einstiegspunkt
  • assets/ – Minifiziertes JS, CSS und Bilder
  • Statische Dateien aus public/

Erstellung des Containers für den Produktivbetrieb

nginx-Konfiguration für React

React-Anwendungen verwenden clientseitiges Routing, was eine spezielle nginx-Konfiguration erfordert. Erstellen Sie nginx.conf:

server {
    listen 80;
    server_name _;

    root /usr/share/nginx/html;
    index index.html;
    # Gzip compression for better performance
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript
               application/x-javascript application/xml+rss
               application/javascript application/json;
    # Security headers (a location with its own add_header drops these)
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    # SPA: Route all paths to index.html for client-side routing
    location / {
        try_files $uri $uri/ /index.html;
    }
    # Cache static assets aggressively
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    # Revalidate HTML on every request so new releases show up immediately
    location ~* \.html$ {
        expires -1;
    }
    # Health check endpoint for monitoring
    location /health {
        access_log off;
        default_type text/plain;
        return 200 "healthy\n";
    }
}

Das entscheidende Element ist try_files $uri $uri/ /index.html, das sicherstellt, dass React Router im Produktivbetrieb korrekt funktioniert – alle Routen erhalten die zentrale Datei index.html.

Dockerfile für den Produktivbetrieb

Erstellen Sie ein optimiertes Dockerfile:

FROM nginx:alpine
# Copy custom nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy production build files
COPY dist/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Dieses Dockerfile verwendet nginx:alpine für ein minimales Image für den Produktivbetrieb (komprimiert unter 30 MB, Stand Oktober 2026), das alles enthält, was zur Bereitstellung Ihrer React-App benötigt wird.

Docker-Compose-Konfiguration

Erstellen Sie docker-compose.yml für eine einfache Bereitstellung:

services:
  my-react-app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: my-react-app
    restart: unless-stopped
    networks:
      - proxy
    labels:
      # Enable Traefik
      - "traefik.enable=true"

      # Define routing rule
      - "traefik.http.routers.myapp.rule=Host(`app.yourdomain.com`)"
      - "traefik.http.routers.myapp.entrypoints=https"
      - "traefik.http.routers.myapp.tls=true"
      - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"

      # Define service port
      - "traefik.http.services.myapp.loadbalancer.server.port=80"

    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:80/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 5s
networks:
  proxy:
    external: true

Wichtige Konfigurationshinweise:

Viele Bereitstellungen scheitern an der Konfiguration der Labels. Beachten Sie, was wir NICHT einschließen:

  • Keine separate HTTP-Router-Definition
  • Keine benutzerdefinierte Redirect-Middleware
  • Keine HTTP-Entrypoint-Konfiguration

Warum? Weil Traefiks globale Konfiguration bereits HTTP-zu-HTTPS-Weiterleitungen übernimmt. In unserer Konfiguration beeinträchtigte das Hinzufügen benutzerdefinierter HTTP-Router dieses Verhalten und verursachte 404-Fehler – genau das Problem, das wir in unserer Debugging-Sitzung gelöst haben.

Bereitstellung auf Ihrem Produktivserver

Voraussetzungen auf Ihrem Server

Ihr Produktivserver benötigt:

Docker-Umgebung:

# Verify Docker is installed
docker --version
docker compose version
# Verify Traefik is running
docker ps | grep traefik
# Verify proxy network exists
docker network ls | grep proxy

Wenn Traefik noch nicht eingerichtet ist, verweisen wir auf unseren Leitfaden für mandantenfähige Docker-Umgebungen, der eine umfassende Traefik-Einrichtung behandelt.

Ausreichend Speicherplatz:

# Check available space
df -h /
# You need at least 2-5GB free for Docker operations

DNS-Konfiguration:

  • Setzen Sie den DNS-Eintrag für app.yourdomain.com auf die IP-Adresse Ihres Servers
  • Warten Sie auf die DNS-Propagierung (normalerweise 5-60 Minuten)

Hochladen Ihrer Anwendung

Übertragen Sie Ihre Anwendung auf den Server:

# From your local machine
scp -r my-react-app/ user@your-server:/opt/
# Or use rsync for efficient updates
rsync -avz --exclude 'node_modules' \
  my-react-app/ user@your-server:/opt/my-react-app/

Container erstellen und starten

Verbinden Sie sich per SSH mit Ihrem Server und führen Sie das Deployment aus:

# Navigate to application directory
cd /opt/my-react-app
# Build the Docker image
docker compose build
# Start the container
docker compose up -d
# Verify it's running
docker compose ps

Überprüfung der Bereitstellung

Prüfen Sie, ob alles funktioniert:

# Test container health internally
docker compose exec my-react-app wget -q -O- http://127.0.0.1/health
# Check Traefik routing (wait 30 seconds for SSL)
curl -I https://app.yourdomain.com
# View container logs
docker compose logs -f

Sie sollten HTTP/2 200 vom curl-Befehl sehen, was den Erfolg bestätigt.

Häufige Bereitstellungsfehler und Lösungen

404-Fehler trotz korrekter Konfiguration

Symptom: Traefik gibt HTTP/2 404 zurück, obwohl der Container intern funktioniert.

Ursache: Mehrere Router-Definitionen für denselben Service ohne korrekte Service-Port-Zuordnung oder benutzerdefinierte HTTP-Router, die Traefiks globale Weiterleitungen überschreiben.

Lösung:

# Remove these labels if present:
# - "traefik.http.middlewares.myapp-redirect.redirectscheme.scheme=https"
# - "traefik.http.routers.myapp-http.rule=Host(`app.yourdomain.com`)"
# - "traefik.http.routers.myapp-http.entrypoints=http"
# - "traefik.http.routers.myapp-http.middlewares=myapp-redirect"
# Keep only HTTPS router:
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.myapp.rule=Host(`app.yourdomain.com`)"
  - "traefik.http.routers.myapp.entrypoints=https"
  - "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
  - "traefik.http.services.myapp.loadbalancer.server.port=80"

Traefiks globale HTTP-zu-HTTPS-Weiterleitung (konfiguriert in traefik.yml) verarbeitet HTTP-Verkehr automatisch. Benutzerdefinierte HTTP-Router pro Service können damit in Konflikt geraten.

Container mit Status „unhealthy“

Symptom: docker compose ps zeigt den Container als "unhealthy" an

Ursache: Health Check nutzt localhost, das zu IPv6 [::1] aufgelöst wird, aber nginx nur auf IPv4 lauscht.

Lösung:

healthcheck:
  # Use explicit IPv4 address instead of localhost
  test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:80/health"]

Docker-Build schlägt mit "No Space Left" fehl

Symptom: Build schlägt mit Speicherplatzfehlern fehl

Lösung:

# Check disk usage
df -h /
# Clean Docker system
docker system prune -a -f
# Remove unused images
docker image prune -a -f
# Remove unused volumes
docker volume prune -f

Wenn die Festplatte tatsächlich voll ist (>95%), müssen Sie Speicherplatz freigeben oder Ihren Speicher erweitern. Docker-Vorgänge benötigen temporären Speicherplatz für Layer-Caching und den Build-Prozess.

SSL-Zertifikat wird nicht generiert

Symptom: curl zeigt nach 10+ Minuten ein selbstsigniertes Zertifikat an

Häufige Ursachen:

  • DNS-Eintrag verweist nicht korrekt auf den Server
  • Port 80/443 nicht aus dem Internet erreichbar
  • Let's-Encrypt-Ratenlimit erreicht (zum Beispiel 5 Zertifikate pro identischer Gruppe von Hostnamen oder 50 pro registrierter Domain alle 7 Tage)

Lösung:

# Verify DNS resolution
dig app.yourdomain.com
# Test port accessibility
curl -I http://app.yourdomain.com
# Check Traefik logs for ACME errors
docker logs traefik 2>&1 | grep -i acme
# Restart Traefik if needed
docker restart traefik

React-Router-404-Fehler beim Aktualisieren

Symptom: App funktioniert beim ersten Laden, zeigt aber 404 an, wenn die Seite auf Routen wie /about neu geladen wird

Ursache: Fehlende try_files-Direktive in der nginx-Konfiguration

Lösung: Stellen Sie sicher, dass Ihre nginx.conf Folgendes enthält:

location / {
    try_files $uri $uri/ /index.html;
}

Dies weist nginx an, index.html für alle Routen bereitzustellen, sodass React Router das Routing clientseitig übernimmt.

Container startet, aber Traefik kann ihn nicht erreichen

Symptom: Container läuft, aber Traefik gibt "Service Unavailable" zurück

Lösung:

# Verify container is on correct network
docker network inspect proxy
# Check if container is listed
docker inspect my-react-app | grep -A 20 Networks
# Ensure proxy network exists
docker network create proxy

Optimierung für den Produktivbetrieb

Bereitstellungen ohne Ausfallzeit implementieren

Aktualisieren Sie Ihre Anwendung mit minimaler Ausfallzeit. Das Neuerstellen eines einzelnen Containers mit docker compose up unterbricht den Datenverkehr weiterhin kurzzeitig; für echte Ausfallfreiheit muss eine zweite fehlerfrei laufende Instanz hinter Traefik bereitstehen, bevor die alte gestoppt wird:

#!/bin/bash
# deploy-update.sh - rebuild and replace the container
# Recreating a single container briefly interrupts traffic (see above)
set -euo pipefail
cd /opt/my-react-app
# Pull latest code (from git or updated files)
git pull origin main
# Build new production assets from the lockfile
npm ci
npm run build
# Build the new image while the old container keeps serving
docker compose build my-react-app
# Replace the container: Compose stops the old one, then starts the new one,
# and --wait returns once the new container reports healthy
docker compose up -d --no-deps --wait my-react-app

Erweiterte Health Checks

Implementieren Sie eine umfassende Zustandsüberwachung:

healthcheck:
  test: |
    wget --no-verbose --tries=1 --spider http://127.0.0.1:80/health &&
    wget --no-verbose --tries=1 --spider http://127.0.0.1:80/
  interval: 30s
  timeout: 5s
  retries: 3
  start_period: 10s

Dies prüft sowohl den Health-Endpunkt als auch die Hauptroute der Anwendung und stellt sicher, dass die gesamte App korrekt reagiert.

Leistungsoptimierung

Optimieren Sie nginx für bessere Leistung:

# Add to nginx.conf
server {
    # ... existing config ...

    # Increase buffer sizes for large headers
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;

    # Enable keep-alive connections
    keepalive_timeout 65;

    # Optimize file serving
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
}

Ressourcenlimits

Verhindern Sie Ressourcenerschöpfung mit Container-Limits:

services:
  my-react-app:
    # ... existing config ...
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

nginx, das statische React-Dateien bereitstellt, benötigt minimale Ressourcen – 512 MB Arbeitsspeicher und ein halber CPU-Kern sind ein sinnvoller Ausgangswert für die Ressourcenbegrenzung; prüfen Sie mit Lasttests, ob die für Ihren Datenverkehr benötigte Zahl gleichzeitiger Zugriffe bewältigt wird.

Warum selbst betriebene Docker-Bereitstellungen wichtig sind

Der eigenständige Betrieb Ihrer React-Anwendungen auf Docker-Infrastruktur gibt Ihnen die vollständige Kontrolle über Ihre Bereitstellungspipeline ohne Vendor-Lock-in. Sie können unbegrenzt Anwendungen auf Ihrer eigenen Infrastruktur bereitstellen, jeden Aspekt des Bereitstellungsprozesses anpassen und nahtlos in Ihre bestehenden selbst betriebenen Dienste integrieren.

Dieser Ansatz funktioniert besonders gut in Kombination mit unserer mandantenfähigen Docker-Architektur, mit der Sie mehrere Kundenanwendungen auf derselben Infrastruktur mit separaten Containern und Netzwerken pro Kunde hosten können.

Automatisierung und CI/CD-Integration

GitHub-Actions-Bereitstellung

Automatisieren Sie Bereitstellungen bei jedem Push:

# .github/workflows/deploy.yml
name: Deploy to Production
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - name: Setup Node.js
        uses: actions/setup-node@v7
        with:
          node-version: '24'
          cache: 'npm'

      - name: Build React app
        run: |
          npm ci
          npm run build

      - name: Deploy to server
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: "dist/,Dockerfile,nginx.conf,docker-compose.yml"
          target: "/opt/my-react-app"

      - name: Restart container
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/my-react-app
            docker compose up -d --build --wait

GitLab-CI/CD-Pipeline

Für GitLab-Benutzer:

# .gitlab-ci.yml
stages:
  - build
  - deploy
build:
  stage: build
  image: node:24
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
deploy:
  stage: deploy
  image: alpine:3.23
  before_script:
    - apk add --no-cache openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    # Trust the server's host key (store `ssh-keyscan your-server` output in SSH_KNOWN_HOSTS)
    - mkdir -p ~/.ssh && echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
  script:
    - scp -r dist/ Dockerfile nginx.conf docker-compose.yml $SERVER_USER@$SERVER_HOST:/opt/my-react-app/
    - ssh $SERVER_USER@$SERVER_HOST "cd /opt/my-react-app && docker compose up -d --build --wait"
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Überwachung Ihres Deployments im Produktivbetrieb

Logging-Strategie

Implementieren Sie umfassendes Logging:

# Add to docker-compose.yml
services:
  my-react-app:
    # ... existing config ...
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Logs effizient anzeigen:

# Real-time logs
docker compose logs -f my-react-app
# Last 100 lines
docker compose logs --tail=100 my-react-app
# Logs from specific time
docker compose logs --since=2h my-react-app
# Filter for errors only
docker compose logs my-react-app | grep -i error

Metriken und Warnungen

Container-Zustand überwachen:

#!/bin/bash
# health-check.sh - Regular health monitoring
CONTAINER="my-react-app"
WEBHOOK_URL="your-notification-webhook"
STATUS=$(docker inspect --format='{{.State.Health.Status}}' $CONTAINER)
if [ "$STATUS" != "healthy" ]; then
    curl -X POST $WEBHOOK_URL \
      -H 'Content-Type: application/json' \
      -d "{\"text\":\"⚠️ Container $CONTAINER is $STATUS\"}"
fi

Führen Sie dies alle 5 Minuten über Cron für eine grundlegende Überwachung aus.

React mit Backend-Infrastruktur verbinden

Ihre React-App muss wahrscheinlich mit Backend-Diensten kommunizieren. Dies lässt sich gut in selbst betriebene Infrastruktur integrieren. Wenn Sie n8n für Workflow-Automatisierung oder Windmill für Backend-Workflows betreiben, konfigurieren Sie korrektes CORS und API-Routing in Ihrer nginx-Konfiguration:

# Add to nginx.conf, above the server block: set Connection only for WebSocket upgrades
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# Inside the server block. Same-origin proxying: the browser makes no
# cross-origin request, so these API calls need no CORS headers
location /api {
    proxy_pass http://your-backend-service:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Dies funktioniert nahtlos, wenn alle Dienste Teil desselben Docker-Netzwerks sind, wie in unserem Leitfaden zur mandantenfähigen Architektur demonstriert.

Umgebungsspezifische Builds

Verschiedene Umgebungen benötigen oft unterschiedliche Konfigurationen:

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig(({ mode }) => ({
  plugins: [react()],
  define: {
    'import.meta.env.VITE_API_URL': JSON.stringify(
      mode === 'production'
        ? 'https://api.yourdomain.com'
        : 'http://localhost:3000'
    ),
  },
  build: {
    outDir: 'dist',
    sourcemap: mode !== 'production',
  },
}))

Builds für verschiedene Umgebungen erstellen:

# Development build
npm run build -- --mode development
# Staging build
npm run build -- --mode staging
# Production build
npm run build -- --mode production

Der eigentliche Wert dieses Setups

Dieser Bereitstellungsansatz ist relevant, wenn Sie:

Mehrere Anwendungen verwalten:

  • React-Apps neben Backend-Diensten auf derselben Infrastruktur bereitstellen
  • Konsistente Bereitstellungsprozesse über alle Projekte hinweg verwenden
  • Selbst betriebene Tools wie n8n und Windmill integrieren

Für Kunden entwickeln:

  • Eigene Domains mit professioneller SSL-Absicherung
  • Vollständige Kontrolle über Infrastruktur und Bereitstellungen
  • Keine Plattformbeschränkungen oder Vendor-Lock-in

Infrastruktur erlernen:

  • Grundlagen der Docker-Containerisierung verstehen
  • Deployment-Probleme im Produktivbetrieb systematisch debuggen

Das hier dokumentierte Setup basiert auf einer realen Debugging-Sitzung – die beschriebenen Probleme sind tatsächlich aufgetreten, und die Lösungen haben tatsächlich funktioniert. Dies macht es wertvoller als theoretische Tutorials, weil Sie die tatsächlichen Fallstricke sehen und erfahren, wie Sie sie vermeiden können.

In Kombination mit unserer mandantenfähigen Docker-Architektur bildet dies ein Fundament für skalierbare, selbst betriebene Anwendungsbereitstellung, die Sie vollständig kontrollieren.

Weiterführende Ressourcen

Weitere Leitfäden zur selbst betriebenen Infrastruktur finden Sie hier:

  • Self-Hosting von n8n für Workflow-Automatisierung – Automatisieren Sie Bereitstellungen und Infrastrukturaufgaben
  • Self-Hosting von Windmill mit Docker – Alternative Plattform für Workflow-Automatisierung
  • Mandantenfähige Docker-Stacks aufbauen – Umfassendes Traefik-Setup für mehrere Anwendungen
  • tva Duplicate Pro – WordPress-Automatisierungstools für Content-Workflows

Diese Leitfäden demonstrieren verschiedene Aspekte des Aufbaus selbst betriebener Infrastruktur, die Ihnen vollständige Kontrolle gibt und gleichzeitig professionelle Standards aufrechterhält.

Professionelle Unterstützung

Die Einrichtung für den Produktivbetrieb geeigneter React-Bereitstellungen umfasst viele infrastrukturelle Überlegungen. Obwohl wir eine umfassende Dokumentation bereitgestellt haben, hat jedes Projekt einzigartige Anforderungen, bestehende Infrastrukturbeschränkungen und spezifische Leistungsanforderungen.

Wenn Sie React-Bereitstellungsinfrastruktur für den Produktiveinsatz implementieren oder Anpassungen für die besonderen Anforderungen Ihrer Kundenprojekte benötigen, unterstützen wir Sie bei:

  • Maßgeschneiderten Bereitstellungspipelines, die auf Ihren Workflow zugeschnitten sind
  • Integration mit bestehenden CI/CD-Systemen
  • Leistungsoptimierung für Anwendungen mit hohem Anfrageaufkommen
  • Multi-Region-Bereitstellungsstrategien
  • Team-Schulungen zu Docker- und Traefik-Best-Practices
  • Laufendes Infrastrukturmanagement und Monitoring

Kontaktieren Sie uns über tva.sg/contact, um Ihre React-Bereitstellungsanforderungen zu besprechen und professionelle Beratung zur Implementierung zu erhalten.

Von der Konfiguration zur Betriebsentscheidung

Die praktische Frage ist nicht, ob sich eine Plattform konfigurieren lässt. Entscheidend ist, ob das Team Zuständigkeiten erklären, Abweichungen erkennen, ohne Improvisation den Betrieb wiederherstellen und nachweisen kann, dass die Änderung das beabsichtigte Ergebnis verbessert hat. Deshalb verbinden wir jede Konfigurationsänderung mit einer verantwortlichen Person, einem Ausgangswert, einem Rücksetzpfad und einem Kontrollzeitraum nach der Änderung. So wird aus einer einmaligen Korrektur eine Fähigkeit für den laufenden Betrieb. Die Betriebsdokumentation sollte den Grund für die Änderung, die geprüften Nachweise, den genauen Umfang und die Person festhalten, die befugt ist, die Änderung zu stoppen oder rückgängig zu machen. Vergleichen Sie nach der Freigabe die vereinbarten Kennzahlen mit dem Ausgangswert und halten Sie das Ergebnis zusammen mit dem Änderungsprotokoll fest. Bleibt die erwartete Verbesserung aus, ist das Rücksetzen ein gültiges Ergebnis und kein Fehlschlag. Diese Disziplin ist wichtiger als jeder einzelne Konfigurationswert. Dieselbe Dokumentation bietet der nächsten für den Betrieb verantwortlichen Person einen verlässlichen Ausgangspunkt und macht spätere Optimierungen zu messbaren Entscheidungen statt zu einer weiteren Runde von Vermutungen.

Weiterführende Beiträge

Weiterführende Beiträge