Files
pfandsystem-demo/dokumentationen/DEPLOYMENT_ANLEITUNG.md
christian d86c898455 chore: initial scaffold (Whitelabel-Fork von Pfandsystem)
- Source-Copy von /root/entwicklung/pfandsystem
- docker-compose.yml umgeschrieben: pfandsystem-demo-* Container, Ports 3308/8083/3003 (alle localhost)
- Traefik-Label fuer pfandsystem.dockly.de
- Erweitertes Multi-Tenant-Schema (tenants, tenant_id auf allen Tabellen)
- Neue Tabellen: kunden_bilder, geraete
- Neue Spalten: kunden.anlieferungshinweis, kunden.lieferzeit_bis
- Rollen: superadmin, admin, user, fahrer
- .env.example + README

Code-Refactor (Tailwind, Multi-Tenant-Middleware, Erweiterungen) folgt.
2026-05-26 12:39:17 +00:00

8.0 KiB

🚀 Deployment-Anleitung: Live-Version erstellen

📋 Übersicht

Dev-Version: /root (pfandsystem.backdigital.de) Live-Version: /var/www/pfandsystem-live (neue-domain.de)


🔧 Schritt-für-Schritt Anleitung

1. Neues Verzeichnis erstellen

# Live-Version Verzeichnis
sudo mkdir -p /var/www/pfandsystem-live
cd /var/www/pfandsystem-live

# Git Repository klonen
git clone ssh://git@49.13.154.75:2244/christian/pfandsystem.git .

# Auf main branch wechseln
git checkout main

2. Umgebungsvariablen anpassen

Frontend .env:

cat > .env << 'EOF'
VITE_API_URL=https://DEINE-NEUE-DOMAIN.de/api
EOF

Backend .env:

cat > backend/.env << 'EOF'
# Database
DB_HOST=localhost
DB_PORT=3307
DB_USER=pfandsystem_live
DB_PASSWORD=NEUES_SICHERES_PASSWORT
DB_NAME=pfandsystem_live

# JWT
JWT_SECRET=NEUER_JWT_SECRET_KEY_HIER

# Server
PORT=3002
NODE_ENV=production

# Resend API
RESEND_API_KEY=re_6BE6Hv6U_H7ggkAT4ApbiSZ5SCo2Cf1qA

# File Upload
UPLOAD_DIR=/var/www/pfandsystem-live/backend/uploads
MAX_FILE_SIZE=10485760
EOF

3. Docker-Compose anpassen

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  # MySQL Datenbank (Live)
  mysql:
    image: mysql:8.0
    container_name: pfandsystem-live-mysql
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: NEUES_ROOT_PASSWORT
      MYSQL_DATABASE: pfandsystem_live
      MYSQL_USER: pfandsystem_live
      MYSQL_PASSWORD: NEUES_SICHERES_PASSWORT
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3307:3306"
    networks:
      - pfandsystem-live-network
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  # phpMyAdmin (Live)
  phpmyadmin:
    image: phpmyadmin:latest
    container_name: pfandsystem-live-phpmyadmin
    restart: unless-stopped
    environment:
      PMA_HOST: mysql
      PMA_PORT: 3306
    ports:
      - "8082:80"
    networks:
      - pfandsystem-live-network
    depends_on:
      - mysql

  # Frontend (Live)
  frontend:
    image: nginx:1.25-alpine
    container_name: pfandsystem-live-frontend
    restart: unless-stopped
    volumes:
      - ./dist:/usr/share/nginx/html:ro
    networks:
      - pfandsystem-live-network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pfandsystem-live.rule=Host(`DEINE-NEUE-DOMAIN.de`)"
      - "traefik.http.routers.pfandsystem-live.entrypoints=web,websecure"
      - "traefik.http.routers.pfandsystem-live.tls=true"
      - "traefik.http.routers.pfandsystem-live.tls.certresolver=letsencrypt"
      - "traefik.http.services.pfandsystem-live.loadbalancer.server.port=80"

volumes:
  mysql_data:
    driver: local

networks:
  pfandsystem-live-network:
    driver: bridge
EOF

4. Traefik Dynamic Config für Backend

mkdir -p /var/www/pfandsystem-live/traefik-config

cat > /var/www/pfandsystem-live/traefik-config/backend.yml << 'EOF'
http:
  routers:
    # Backend API Router (Live)
    pfandsystem-live-api:
      rule: "Host(`DEINE-NEUE-DOMAIN.de`) && PathPrefix(`/api`)"
      service: pfandsystem-live-api
      entryPoints:
        - web
        - websecure
      tls:
        certResolver: letsencrypt
      priority: 100

    # Backend Uploads Router (Live)
    pfandsystem-live-uploads:
      rule: "Host(`DEINE-NEUE-DOMAIN.de`) && PathPrefix(`/uploads`)"
      service: pfandsystem-live-api
      entryPoints:
        - web
        - websecure
      tls:
        certResolver: letsencrypt
      priority: 100

  services:
    # Backend Service (Live)
    pfandsystem-live-api:
      loadBalancer:
        servers:
          - url: "http://172.17.0.1:3002"
EOF

5. Traefik-Config in bestehenden Traefik einbinden

# Kopiere Config in Traefik dynamic Ordner
sudo cp /var/www/pfandsystem-live/traefik-config/backend.yml /root/traefik/dynamic/pfandsystem-live.yml

# Traefik neu laden (erkennt automatisch neue Configs)
docker restart pfandsystem-traefik

6. Datenbank initialisieren

# Docker Container starten
cd /var/www/pfandsystem-live
docker compose up -d mysql phpmyadmin

# Warte bis MySQL bereit ist
sleep 30

# SQL Schema importieren
docker exec -i pfandsystem-live-mysql mysql -upfandsystem_live -pNEUES_SICHERES_PASSWORT pfandsystem_live < backend/schema.sql

# Admin-User erstellen
cd backend
npm install
node scripts/create-admin.js

7. Frontend bauen

cd /var/www/pfandsystem-live

# Dependencies installieren
npm install

# Frontend bauen
npm run build

# Manifest-Links fixen
node fix-manifest-link.cjs

8. Backend starten

cd /var/www/pfandsystem-live/backend

# Dependencies installieren
npm install

# Backend als Service starten (mit PM2)
npm install -g pm2
pm2 start server.js --name pfandsystem-live
pm2 save
pm2 startup

9. Frontend-Container starten

cd /var/www/pfandsystem-live
docker compose up -d frontend

10. Logo und Branding anpassen

Logo ersetzen:

# Eigenes Logo (192x192 und 512x512)
cp /pfad/zu/deinem/logo-192.png /var/www/pfandsystem-live/public/logo-192.png
cp /pfad/zu/deinem/logo-512.png /var/www/pfandsystem-live/public/logo-512.png

# Favicon
cp /pfad/zu/deinem/favicon.ico /var/www/pfandsystem-live/public/favicon.ico

Manifest anpassen:

nano /var/www/pfandsystem-live/public/manifest.json

Ändere:

{
  "name": "Dein Firmenname - Pfandsystem",
  "short_name": "Dein Pfandsystem",
  "theme_color": "#DEINE_FARBE",
  "background_color": "#DEINE_FARBE"
}

Farben anpassen:

nano /var/www/pfandsystem-live/src/index.css

Ändere Primary-Color, etc.

Frontend neu bauen:

cd /var/www/pfandsystem-live
npm run build
node fix-manifest-link.cjs
docker restart pfandsystem-live-frontend

🧪 Testing

1. DNS konfigurieren:

DEINE-NEUE-DOMAIN.de → A-Record → Server-IP

2. Testen:

# SSL-Zertifikat wird automatisch von Traefik generiert
curl -I https://DEINE-NEUE-DOMAIN.de

# Login testen
curl https://DEINE-NEUE-DOMAIN.de/api/auth/login \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@pfandsystem.de","password":"admin123"}'

3. Im Browser öffnen:

https://DEINE-NEUE-DOMAIN.de

📊 Übersicht der Ports

Service Dev Live
MySQL 3306 3307
phpMyAdmin 8081 8082
Backend 3001 3002
Frontend via Traefik via Traefik

🔄 Updates deployen

cd /var/www/pfandsystem-live

# Neueste Version holen
git pull origin main

# Frontend neu bauen
npm run build
node fix-manifest-link.cjs
docker restart pfandsystem-live-frontend

# Backend neu starten
pm2 restart pfandsystem-live

🛡️ Sicherheit

  1. Passwörter ändern:

    • MySQL Root-Passwort
    • MySQL User-Passwort
    • JWT Secret
    • Admin-Passwort (nach erstem Login)
  2. Firewall:

    # Nur notwendige Ports öffnen
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw allow 22/tcp
    
  3. Backups:

    # Automatisches Backup einrichten
    crontab -e
    # Täglich um 2 Uhr
    0 2 * * * /var/www/pfandsystem-live/backup.sh
    

Checkliste

  • Verzeichnis erstellt
  • Git geklont
  • .env Dateien angepasst
  • docker-compose.yml angepasst
  • Traefik-Config erstellt
  • Datenbank initialisiert
  • Admin-User erstellt
  • Frontend gebaut
  • Backend gestartet (PM2)
  • Frontend-Container gestartet
  • Logo/Branding angepasst
  • DNS konfiguriert
  • SSL-Zertifikat generiert
  • Login getestet
  • Alle Funktionen getestet

🎯 Zusammenfassung

Dev-Version:

  • Verzeichnis: /root
  • Domain: pfandsystem.backdigital.de
  • MySQL Port: 3306
  • Backend Port: 3001

Live-Version:

  • Verzeichnis: /var/www/pfandsystem-live
  • Domain: DEINE-NEUE-DOMAIN.de
  • MySQL Port: 3307
  • Backend Port: 3002

Beide Versionen laufen parallel auf derselben Instanz mit eigenem Traefik-Routing!