Zum Inhalt

calServer v2 — Installationsanleitung

Voraussetzungen

  • Docker >= 24.0 und Docker Compose >= 2.20
  • calServer v1 laeuft bereits (docker-compose.yml)
  • Domain zeigt per DNS auf den Server (A-Record)
  • Port 80 und 443 offen (fuer Let's Encrypt HTTP-01 Challenge)
  • Mindestens 1 GB zusaetzlicher RAM (API v2 ~200MB, Frontend ~100MB, Redis ~50MB)

Schnellstart (Demo/Develop Server)

1. .env konfigurieren

cd /var/calserver

Folgende Variablen zur bestehenden .env hinzufuegen:

# v2 Services aktivieren
ENABLE_V2=true

# Laravel App Key generieren (einmalig):
LARAVEL_APP_KEY=base64:$(docker run --rm php:8.3-cli php -r "echo base64_encode(random_bytes(32));")

# Umgebung
APP_ENV=production
APP_DEBUG=false
APP_URL=https://develop.net-cal.com  # Gleiche Domain wie v1!
DB_PREFIX=thermo_

Wichtig: APP_URL muss die gleiche Domain wie DOMAIN sein. v2 laeuft nicht auf einer separaten Domain, sondern unter /v2/ und /api/v2/.

2. Laravel App Key generieren

# Option A: Via Docker
docker run --rm php:8.3-cli php -r "echo 'base64:' . base64_encode(random_bytes(32)) . PHP_EOL;"

# Option B: Falls Laravel-Container bereits laeuft
docker exec calserver-api-v2 php artisan key:generate --show

Den generierten Schluessel in .env als LARAVEL_APP_KEY eintragen.

3. Docker Images pullen

# Manuell (ohne CI/CD)
docker pull calhelp/calserver-api-v2:release-latest
docker pull calhelp/calserver-frontend:release-latest

# Oder spezifischer Tag
docker pull calhelp/calserver-api-v2:develop-latest
docker pull calhelp/calserver-frontend:develop-latest

4. Deployment starten

sudo ./deploy.sh

Das Script erkennt automatisch ENABLE_V2=true und: 1. Haengt docker-compose.v2.yml als Overlay an 2. Startet die v2-Services (API, Frontend, Redis) 3. Prueft Health-Checks fuer alle Services

5. Verifizieren

# v1 (unveraendert)
curl -s https://develop.net-cal.com/ | head -5

# v2 API Health-Check
curl -s https://develop.net-cal.com/api/v2/health
# → {"status":"ok"}

# v2 Frontend
curl -s -o /dev/null -w "%{http_code}" https://develop.net-cal.com/v2/
# → 200

# Container-Status
docker ps --filter name=calserver --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

Erwartete Ausgabe:

NAMES                 STATUS          PORTS
calserver             Up 2 minutes    0.0.0.0:8080->8080/tcp
calserver-api-v2      Up 2 minutes    8081/tcp
calserver-frontend    Up 2 minutes    3000/tcp
calserver-redis       Up 2 minutes    6379/tcp

Let's Encrypt SSL

Wie es funktioniert

v2 nutzt das gleiche SSL-Zertifikat wie v1:

Internet
   │
   ├── https://develop.net-cal.com/          → calserver (v1, Yii)
   ├── https://develop.net-cal.com/api/v2/   → calserver-api-v2 (Laravel)
   └── https://develop.net-cal.com/v2/       → calserver-frontend (Nuxt)
   │
   ▼
┌─────────────────────────────────────────────┐
│ nginx-proxy (nginxproxy/nginx-proxy)          │
│   - SSL-Terminierung via Let's Encrypt       │
│   - Zertifikat: *.net-cal.com               │
│   - vhost.d/default_location:               │
│     /api/v2/* → calserver-api-v2:8081       │
│     /v2/*     → calserver-frontend:3000     │
│     /*        → calserver:8080 (default)    │
└─────────────────────────────────────────────┘

Kein zusaetzliches Zertifikat noetig

Der nginx-proxy Container mit acme-companion: 1. Erkennt LETSENCRYPT_HOST und VIRTUAL_HOST aus dem calserver-Container 2. Fordert ein Zertifikat bei Let's Encrypt an (HTTP-01 Challenge) 3. Speichert es unter /etc/nginx/certs/ 4. Konfiguriert automatisch HTTPS fuer den VIRTUAL_HOST 5. Die vhost.d/default_location Datei wird automatisch in den SSL-Server-Block included 6. Ergebnis: /api/v2/* und /v2/* sind sofort per HTTPS erreichbar

Konfiguration pruefen

# Zertifikat pruefen
docker exec nginx-proxy ls -la /etc/nginx/certs/ | grep net-cal

# vhost.d Location pruefen
docker exec nginx-proxy cat /etc/nginx/vhost.d/default_location

# Nginx-Config testen
docker exec nginx-proxy nginx -T 2>&1 | grep -A5 "location /api/v2"

Let's Encrypt Staging (Testserver)

Auf Testservern sollte die Let's Encrypt Staging-Umgebung verwendet werden, um nicht in das Rate Limit (5 Zertifikate pro Woche pro Domain) zu geraten.

In .env setzen:

LETSENCRYPT_TEST=true

Der acme-companion nutzt dann den Staging-Server (acme-staging-v02.api.letsencrypt.org). Staging-Zertifikate werden im Browser als "nicht vertrauenswuerdig" angezeigt (Issuer: "Fake LE Intermediate X1"), aber die SSL-Kette funktioniert korrekt.

Fuer Production-Server die Variable weglassen oder leer lassen:

#LETSENCRYPT_TEST=

Let's Encrypt erneuern

Passiert automatisch durch den acme-companion Container. Wenn der calserver Container LETSENCRYPT_RESTART_CONTAINER=true hat, wird bei Erneuerung auch nginx-proxy neu geladen.

Manuell bauen (ohne CI/CD)

Falls die Images lokal gebaut werden sollen:

# Aus dem Repository-Root:

# API v2 Image
docker build -f Dockerfile.laravel -t calhelp/calserver-api-v2:local .

# Frontend v2 Image
docker build -f Dockerfile.frontend -t calhelp/calserver-frontend:local .

Umgebungsvariablen Referenz

Pflicht (in .env)

Variable Beschreibung Beispiel
ENABLE_V2 v2-Services aktivieren true
LARAVEL_APP_KEY Laravel Encryption Key base64:abc123...
APP_URL Basis-URL (muss DOMAIN matchen) https://develop.net-cal.com
DB_PREFIX Datenbank-Tabellen-Prefix thermo_

Optional (Defaults vorhanden)

Variable Default Beschreibung
V2_STANDALONE false true = V2 ohne V1: docker-compose.yml wird gar nicht geladen, es entstehen also weder der Yii-Container noch die V1-MySQL. Impliziert ENABLE_V2=true. Einzelheiten in docs-v2/entwicklung/v2-autarkie-pruefung.md
LETSENCRYPT_TEST (leer) true = Let's Encrypt Staging (kein Rate Limit)
APP_ENV production Laravel Environment
APP_DEBUG false Debug-Modus (nie true in Produktion!)
PUSHER_APP_ID (aus v1) Fuer Live-Updates
PUSHER_KEY (aus v1) Fuer Live-Updates
PUSHER_SECRET (aus v1) Fuer Live-Updates
PUSHER_CLUSTER (aus v1) Fuer Live-Updates

Bereits vorhanden (shared mit v1)

Diese Variablen werden automatisch an v2 weitergereicht: - DB_HOST, DB_DATABASE, DB_USER, DB_PASSWORD (MySQL) - DOMAIN, FILE_MANAGER_PATH - PUSHER_* (Real-Time Updates)

v2 deaktivieren

# In .env:
ENABLE_V2=false

# Neu deployen:
sudo ./deploy.sh

# Oder manuell v2-Container stoppen:
docker stop calserver-api-v2 calserver-frontend calserver-redis
docker rm calserver-api-v2 calserver-frontend calserver-redis

v1 laeuft dann alleine weiter — ohne Auswirkungen.

Troubleshooting

v2 API antwortet nicht

# Container-Logs pruefen
docker logs calserver-api-v2 --tail 50

# Haeufige Ursache: LARAVEL_APP_KEY fehlt oder ist ungueltig
docker exec calserver-api-v2 php artisan key:generate --show

# PHP-FPM laeuft?
docker exec calserver-api-v2 ps aux | grep php-fpm

Frontend zeigt leere Seite

# Container-Logs pruefen
docker logs calserver-frontend --tail 50

# API-Base-URL korrekt?
docker exec calserver-frontend printenv | grep NUXT
# NUXT_PUBLIC_API_BASE sollte https://develop.net-cal.com/api/v2 sein

Redis-Verbindung fehlgeschlagen

# Redis laeuft?
docker exec calserver-redis redis-cli ping
# → PONG

# Von API-Container aus erreichbar?
docker exec calserver-api-v2 php -r "echo @fsockopen('redis', 6379) ? 'OK' : 'FAIL';"

Let's Encrypt Zertifikat fehlt

# Companion-Logs pruefen
docker logs letsencrypt-nginx-proxy --tail 30

# DNS korrekt?
dig +short develop.net-cal.com

# Port 80 offen? (fuer HTTP-01 Challenge)
curl -v http://develop.net-cal.com/.well-known/acme-challenge/test 2>&1 | head -20

Nginx-Proxy Routing pruefen

# Aktive Nginx-Config anzeigen
docker exec nginx-proxy nginx -T 2>&1 | grep -B2 -A10 "location /api/v2"

# vhost.d Dateien pruefen
docker exec nginx-proxy ls -la /etc/nginx/vhost.d/

# Nginx neu laden (ohne Restart)
docker exec nginx-proxy nginx -s reload

CI/CD Pipeline

Die v2-Services werden automatisch vom CI/CD deployed:

  1. Push auf develop → Images mit Tag develop-latest gebaut und deployed
  2. Push auf master/release/* → Images mit Tag release-latest gebaut und deployed

Pipeline-Ablauf

┌───────────────────────────────────────────────────┐
│ GitHub Actions CI                                  │
├───────────────────────────────────────────────────┤
│                                                   │
│  ┌─────────────┐  ┌──────────────┐  ┌──────────┐ │
│  │ build-v1    │  │ build-api-v2 │  │ build-fe │ │
│  │ (Yii)       │  │ (Laravel)    │  │ (Nuxt)   │ │
│  └──────┬──────┘  └──────┬───────┘  └────┬─────┘ │
│         │                │               │        │
│         └────────┬───────┴───────────────┘        │
│                  ▼                                 │
│         ┌────────────────┐                        │
│         │  deploy-dev    │ (SSH → deploy.sh)       │
│         │  deploy-demo   │                        │
│         └────────────────┘                        │
└───────────────────────────────────────────────────┘

Die deploy.sh erkennt ENABLE_V2=true auf dem Zielserver und startet automatisch alle v2-Services mit.