From efef2125444014aac618002b7ed5f3ff3fd2a4d7 Mon Sep 17 00:00:00 2001 From: Gerd Date: Tue, 15 Sep 2026 17:10:18 +0200 Subject: [PATCH] feat(deploy): Image-Promotion, deploy.env, Health-Check-Fix und Anleitungen - Deploy-Scripts: Image-Promotion statt Rebuild (docker tag + up -d), deploy.env fuer Server-Konfiguration, -p fuer Projekt-Namen, Health-Check mit Host-Header und /xhr/health-check - docker-compose.prod.yaml: name-Feld entfernt (Projekt-Name per -p) - deploy.env.example als Vorlage hinzugefuegt - .vibe/skills/client-build/SKILL.md aus Git-Index entfernt (gitignore) - Deployment-Anleitung: Zugangsdaten, deploy.env, Image-Promotion, prod ohne eigenes Repo, git-clone-Hinweis, Log-Befehle mit -p - Deploy-lokal-testen.md: neue Anleitung fuer lokales Testen Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .vibe/skills/client-build/SKILL.md | 54 ------ Dokumentationen/Deploy-lokal-testen.md | 229 ++++++++++++++++++++++++ Dokumentationen/Deployment-Anleitung.md | 125 ++++++++++--- docker-compose.prod.yaml | 4 +- scripts/deploy-kbcrm-prod.sh | 67 +++++-- scripts/deploy-kbcrm-test.sh | 44 ++++- scripts/deploy.env.example | 23 +++ 7 files changed, 440 insertions(+), 106 deletions(-) delete mode 100644 .vibe/skills/client-build/SKILL.md create mode 100644 Dokumentationen/Deploy-lokal-testen.md mode change 100644 => 100755 scripts/deploy-kbcrm-prod.sh mode change 100644 => 100755 scripts/deploy-kbcrm-test.sh create mode 100644 scripts/deploy.env.example diff --git a/.vibe/skills/client-build/SKILL.md b/.vibe/skills/client-build/SKILL.md deleted file mode 100644 index ae6f3bb..0000000 --- a/.vibe/skills/client-build/SKILL.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: client-build -description: Load this skill after modifying TypeScript files under Client/ to compile and bundle the frontend. Runs tsc and rollup to produce the deployable JS bundle in NGINX_Server/html/static/. ---- - -# Client Build - -Führt den TypeScript- und Rollup-Build für die Client-Seite aus. Wird benötigt, -nachdem `.ts`-Dateien unter `Client/` geändert wurden, damit die kompilierten -Bundles in `NGINX_Server/html/static/` aktualisiert werden. - -## Build-Schritte - -1. **TypeScript kompilieren** — kompiliert alle `.ts`-Dateien nach `Client/tsout/`: - ```bash - cd /usr/opt/pythonapp/Client && npx tsc - ``` - Bei Fehlern: Ausgabe lesen, Fehler beheben, erneut ausführen. - -2. **Rollup bundle** — bündelt `tsout/index.js` zu den statischen JS-Dateien: - ```bash - cd /usr/opt/pythonapp/Client && npx rollup -c - ``` - `rollup -c` liest die Konfiguration aus `rollup.config.mjs`. Es fasst alle - kompilierten `.js`-Dateien plus Mithril zu einem selbstausführenden Bundle - (Format: iife) zusammen und schreibt zwei Dateien nach - `NGINX_Server/html/static/`: - - `kbp_crm_00.00.01.js` — unminifiziert (für Debug) - - `kbp_crm_00.00.01.min.js` — minifiziert via terser (für Produktion) - - Die Dateinamen setzen sich aus `projectname` und `version` aus `config.ini` - zusammen (wird in `rollup.config.mjs` via `inireader.mjs` gelesen). - -## Beide Schritte in einem Aufruf - -```bash -cd /usr/opt/pythonapp/Client && npx tsc && npx rollup -c -``` - -## Wann ausführen - -- Nach jeder Änderung an `.ts`-Dateien unter `Client/` (Modelle, Komponenten, - Widgets, index.ts) -- Vor einem Commit, der Client-Änderungen enthält, damit die deploybaren - Bundles aktuell sind -- Nicht nötig bei reinen Server-Änderungen (`App_Server/`) - -## Fehlerbehandlung - -- **tsc-Fehler:** TypeScript-Compiler-Fehler müssen vor dem Rollup-Schritt - behoben werden — Rollup kann nicht ohne erfolgreiche Kompilierung bündeln. -- **rollup-Fehler:** Meist fehlende Imports oder Pfadprobleme. Die - `rollup.config.mjs` erwartet `tsout/index.js` als Input — sicherstellen, - dass tsc erfolgreich war. diff --git a/Dokumentationen/Deploy-lokal-testen.md b/Dokumentationen/Deploy-lokal-testen.md new file mode 100644 index 0000000..8c295e0 --- /dev/null +++ b/Dokumentationen/Deploy-lokal-testen.md @@ -0,0 +1,229 @@ +# Anleitung: Deploy-Prozess lokal auf dem Entwicklungsrechner testen + +Diese Anleitung beschreibt, wie der komplette Deploy-Prozess (test-prod +und Prod-Promotion) lokal auf dem Entwicklungsrechner getestet werden kann — +ohne Git-Hook, ohne Remote-Server. Voraussetzung: Docker und Docker Compose +sind auf dem Host installiert (nicht im Dev-Container, sondern auf dem +Betriebssystem des Rechners). + +--- + +## 1. Voraussetzungen + +- Docker und Docker Compose auf dem Host installiert +- Git-Repo lokal vorhanden (oder Remote-URL fuer Clone) +- Freie Ports: 8080 (test-prod) und 8081 (prod) + +--- + +## 2. Verzeichnisstruktur anlegen + +```bash +mkdir -p /tmp/deploy-test/{test-prod/repo,scripts,test-prod/data,prod/data,test-prod/certs,prod/certs} +``` + +--- + +## 3. Repository klonen + +```bash +# Entwender vom Remote-Server: +git clone https://git.everdc.eu/chmln-app-dev/kbcrm /tmp/deploy-test/test-prod/repo + +# Oder vom lokalen Repo (schneller, kein Netzwerk noetig): +git clone /pfad/zum/kbcrm /tmp/deploy-test/test-prod/repo +``` + +--- + +## 4. `.env` fuer Test-Prod anlegen + +```bash +cp /tmp/deploy-test/test-prod/repo/env-sample /tmp/deploy-test/test-prod/.env +vi /tmp/deploy-test/test-prod/.env +``` + +Minimal-Konfiguration fuer lokales Testen (SSL aus, keine Zertifikate noetig): + +```bash +# NGINX-Server +NGINX_USE_SSL=false +NGINX_HOST_PORT=8080 +NGINX_SERVER_NAME=localhost +# Auch bei SSL=false muessen die Variablen gesetzt sein (Compose bindet den Pfad ein) +NGINX_CERTS=/tmp/deploy-test/test-prod/certs +NGINX_CERT=placeholder +NGINX_CERT_KEY=placeholder + +# Python App-Server +PYTHON_DB_DIR=/tmp/deploy-test/test-prod/data + +# OIDC-Settings (ggf. anpassen oder Platzhalter fuer lokales Testen) +ZITADEL_ISSUER=https://id.vmlx.de +ZITADEL_CLIENT_ID=local-test +ZITADEL_CLIENT_SECRET=local-test +ZITADEL_REDIRECT_URI=http://localhost:8080/auth/callback +ZITADEL_SCOPES=openid,profile,email +``` + +--- + +## 5. `.env` fuer Prod anlegen + +```bash +cp /tmp/deploy-test/test-prod/repo/env-sample /tmp/deploy-test/prod/.env +vi /tmp/deploy-test/prod/.env +``` + +```bash +NGINX_USE_SSL=false +NGINX_HOST_PORT=8081 +NGINX_SERVER_NAME=localhost +NGINX_CERTS=/tmp/deploy-test/prod/certs +NGINX_CERT=placeholder +NGINX_CERT_KEY=placeholder +PYTHON_DB_DIR=/tmp/deploy-test/prod/data +ZITADEL_ISSUER=https://id.vmlx.de +ZITADEL_CLIENT_ID=local-test +ZITADEL_CLIENT_SECRET=local-test +ZITADEL_REDIRECT_URI=http://localhost:8081/auth/callback +ZITADEL_SCOPES=openid,profile,email +``` + +--- + +## 6. Deploy-Scripts und deploy.env kopieren + +```bash +cp /tmp/deploy-test/test-prod/repo/scripts/deploy-kbcrm-test.sh /tmp/deploy-test/scripts/ +cp /tmp/deploy-test/test-prod/repo/scripts/deploy-kbcrm-prod.sh /tmp/deploy-test/scripts/ +cp /tmp/deploy-test/test-prod/repo/scripts/deploy.env.example /tmp/deploy-test/scripts/deploy.env +chmod +x /tmp/deploy-test/scripts/*.sh +``` + +`deploy.env` anpassen: + +```bash +vi /tmp/deploy-test/scripts/deploy.env +``` + +```bash +# --- Test-Prod Umgebung --- +DEPLOY_REPO_DIR=/tmp/deploy-test/test-prod/repo +DEPLOY_ENV_FILE=/tmp/deploy-test/test-prod/.env +DEPLOY_PROJECT_NAME=kbptest +DEPLOY_HEALTH_PORT=8080 + +# --- Prod Umgebung --- +DEPLOY_PROD_COMPOSE_FILE=/tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml +DEPLOY_PROD_ENV_FILE=/tmp/deploy-test/prod/.env +DEPLOY_PROD_PROJECT_NAME=kbpprod +DEPLOY_PROD_TEST_PROJECT_NAME=kbptest +DEPLOY_PROD_HEALTH_PORT=8081 +``` + +--- + +## 7. Test-Deploy ausfuehren + +```bash +/tmp/deploy-test/scripts/deploy-kbcrm-test.sh +``` + +Das Script: +1. Pullt den aktuellen Code (falls vom Remote geklont) oder nutzt den lokalen Stand +2. Baut beide Images (NGINX mit TypeScript-Build, Python mit Anwendungscode) +3. Startet die Container +4. Fuehrt einen Health-Check durch + +Erster Build dauert einige Minuten (Node.js-Stage, npm install, tsc+rollup, +pip install). Folge-Builds sind durch Docker-Layer-Caching schneller. + +Health-Check manuell: + +```bash +curl http://localhost:8080/xhr/health-check +``` + +--- + +## 8. Prod-Promotion testen + +Voraussetzung: der Test-Deploy wurde erfolgreich durchgefuehrt — die +Images `kbptest-pythonapp` und `kbptest-nginx-proxy` existieren. + +Die Promotion braucht kein eigenes Prod-Repo — die Compose-Datei +wird aus dem test-prod-Repo gelesen. + +Dann die Promotion ausfuehren: + +```bash +/tmp/deploy-test/scripts/deploy-kbcrm-prod.sh +``` + +Das Script: +1. Fragt "yes/no" (mit "yes" bestaetigen) +2. Taggt die Images von `kbptest-*` nach `kbpprod-*` +3. Startet die Prod-Container (ohne Rebuild) +4. Health-Check + +Health-Check manuell: + +```bash +curl http://localhost:8081/xhr/health-check +``` + +--- + +## 9. Container pruefen + +```bash +# Laufende Container anzeigen +docker compose -p kbptest --env-file /tmp/deploy-test/test-prod/.env \ + -f /tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml ps + +docker compose -p kbpprod --env-file /tmp/deploy-test/prod/.env \ + -f /tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml ps + +# Logs anzeigen +docker compose -p kbptest --env-file /tmp/deploy-test/test-prod/.env \ + -f /tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml logs + +docker compose -p kbpprod --env-file /tmp/deploy-test/prod/.env \ + -f /tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml logs +``` + +--- + +## 10. Aufraeumen + +Nach dem Testen alle Container und Images entfernen: + +```bash +# Test-Container stoppen und entfernen +docker compose -p kbptest --env-file /tmp/deploy-test/test-prod/.env \ + -f /tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml down + +# Prod-Container stoppen und entfernen +docker compose -p kbpprod --env-file /tmp/deploy-test/prod/.env \ + -f /tmp/deploy-test/test-prod/repo/docker-compose.prod.yaml down + +# Images entfernen +docker rmi kbptest-pythonapp kbptest-nginx-proxy kbpprod-pythonapp kbpprod-nginx-proxy 2>/dev/null + +# Verzeichnis loeschen +rm -rf /tmp/deploy-test +``` + +--- + +## 11. Typische Probleme + +| Problem | Ursache | Loesung | +|---|---|---| +| `docker compose` not found | Docker Compose Plugin fehlt | `docker compose` muss als Plugin installiert sein (nicht `docker-compose`) | +| Port bereits belegt | Anderer Dienst auf 8080/8081 | Anderen Port in `.env` und `deploy.env` setzen | +| `COPY failed` im Build | `.dockerignore` schliesst benoetigte Dateien aus | `.dockerignore` im Repo-Root pruefen | +| Health-Check schlaegt fehl | Container braucht laenger als 10 Sek | `sleep 10` im Script erhoehen oder Logs pruefen | +| OIDC-Login schlaegt fehl | Redirect-URI stimmt nicht | `ZITADEL_REDIRECT_URI` in `.env` an Port anpassen | +| `git fetch` schlaegt fehl | Keine Zugangsdaten konfiguriert | Lokales Repo verwenden oder Credentials einrichten | diff --git a/Dokumentationen/Deployment-Anleitung.md b/Dokumentationen/Deployment-Anleitung.md index 736d052..6ebf50c 100644 --- a/Dokumentationen/Deployment-Anleitung.md +++ b/Dokumentationen/Deployment-Anleitung.md @@ -58,6 +58,23 @@ Folgende Software muss installiert sein: Docker Compose muss als Plugin installiert sein (Befehl: `docker compose`, nicht `docker-compose`). +### Git-Zugangsdaten konfigurieren + +Das `git clone` und `git fetch` in den Deploy-Scripts nutzen die +Git-Credentials, die auf dem Deploy-Server konfiguriert sind. Die +Zugangsdaten stehen nicht in den Scripts oder Konfigurationsdateien. + +Drei Moeglichkeiten: + +| Methode | Einrichtung | Wo hinterlegt | +|---|---|---| +| SSH-Key | `git clone git@git.everdc.eu:.../kbcrm` (SSH-URL verwenden) | `~/.ssh/id_rsa` auf dem Deploy-Server | +| Git-Credential-Store | `git config --global credential.helper store` | `~/.git-credentials` auf dem Deploy-Server | +| Deploy-Token (Gitea) | Token in Remote-URL: `https://token:secret@git.everdc.eu/...` | In der `origin`-URL des geklonten Repos | + +Empfohlen: SSH-Key oder Deploy-Token. Der Credential-Store speichert +Passwoerter im Klartext und sollte nur fuer Test-Umgebungen verwendet werden. + --- ## 3. Verzeichnisstruktur auf dem Deploy-Server @@ -67,14 +84,14 @@ Es werden zwei Umgebungen (test-prod und prod) parallel betrieben: ``` /opt/kbcrm/ ├── test-prod/ -│ ├── repo/ ← git clone des Repos +│ ├── repo/ ← git clone des Repos (einziges Repo auf dem Server) │ └── .env ← test-prod Umgebung (eigene Ports, eigene DB) ├── prod/ -│ ├── repo/ -│ └── .env ← prod Umgebung +│ └── .env ← prod Umgebung (kein eigenes Repo — Images per docker tag) └── scripts/ ├── deploy-kbcrm-test.sh ← aus dem Repo (scripts/) - └── deploy-kbcrm-prod.sh ← aus dem Repo (scripts/) + ├── deploy-kbcrm-prod.sh ← aus dem Repo (scripts/) + └── deploy.env ← Server-spezifische Konfiguration (nicht im Repo) ``` Die SQLite-Datenbanken liegen ausserhalb des Repos in einem bind-mount @@ -89,11 +106,16 @@ Die SQLite-Datenbanken liegen ausserhalb des Repos in einem bind-mount ```bash sudo mkdir -p /opt/kbcrm/test-prod /opt/kbcrm/prod -# Test-Prod Repository +# Repository klonen (nur einmal — prod nutzt die Images aus test-prod) +# WICHTIG: git clone wird nur beim ersten Mal ausgefuehrt. Wenn das Verzeichnis +# bereits existiert (z.B. .env wurde bereits abgelegt), schlaegt clone fehl. +# Weitere Updates werden durch das deploy-kbcrm-test.sh Script via +# git fetch + git reset --hard durchgefuehrt — kein manueller clone mehr. sudo git clone https://git.everdc.eu/chmln-app-dev/kbcrm /opt/kbcrm/test-prod/repo -# Prod Repository -sudo git clone https://git.everdc.eu/chmln-app-dev/kbcrm /opt/kbcrm/prod/repo +# Falls das Verzeichnis bereits existiert und aktualisiert werden soll: +# cd /opt/kbcrm/test-prod/repo && git fetch origin main && git reset --hard origin/main +# Oder einfach: /opt/kbcrm/scripts/deploy-kbcrm-test.sh ``` ### 4.2. `.env`-Dateien anlegen @@ -104,8 +126,8 @@ Kopieren Sie die Vorlage aus dem Repo und passen Sie die Werte an: # Test-Prod cp /opt/kbcrm/test-prod/repo/env-sample /opt/kbcrm/test-prod/.env -# Prod -cp /opt/kbcrm/prod/repo/env-sample /opt/kbcrm/prod/.env +# Prod (Vorlage aus test-prod-Repo) +cp /opt/kbcrm/test-prod/repo/env-sample /opt/kbcrm/prod/.env ``` ### 4.3. `.env` fuer Test-Prod anpassen @@ -194,12 +216,44 @@ zentralen Ort: ```bash sudo mkdir -p /opt/kbcrm/scripts sudo cp /opt/kbcrm/test-prod/repo/scripts/deploy-kbcrm-test.sh /opt/kbcrm/scripts/ -sudo cp /opt/kbcrm/prod/repo/scripts/deploy-kbcrm-prod.sh /opt/kbcrm/scripts/ +sudo cp /opt/kbcrm/test-prod/repo/scripts/deploy-kbcrm-prod.sh /opt/kbcrm/scripts/ sudo chmod +x /opt/kbcrm/scripts/*.sh ``` -Passen Sie die Pfad-Variablen am Anfang der Scripts an, falls Ihre -Verzeichnisstruktur abweicht. +### 4.8. `deploy.env` anlegen (Server-spezifische Konfiguration) + +Die Deploy-Scripts laden ihre Server-spezifische Konfiguration (Pfade, Ports, +Projekt-Namen) aus einer Datei `deploy.env`, die im gleichen Verzeichnis wie +die Scripts liegen muss. Diese Datei ist **nicht Teil des Repos** und wird +nicht per `git pull` ueberschrieben. + +Kopieren Sie die Vorlage und passen Sie die Werte an: + +```bash +cp /opt/kbcrm/test-prod/repo/scripts/deploy.env.example /opt/kbcrm/scripts/deploy.env +vi /opt/kbcrm/scripts/deploy.env +``` + +Inhalt der `deploy.env`: + +```bash +# --- Test-Prod Umgebung (fuer deploy-kbcrm-test.sh) --- +DEPLOY_REPO_DIR=/opt/kbcrm/test-prod/repo +DEPLOY_ENV_FILE=/opt/kbcrm/test-prod/.env +DEPLOY_PROJECT_NAME=kbptest +DEPLOY_HEALTH_PORT=8443 + +# --- Prod Umgebung (fuer deploy-kbcrm-prod.sh) --- +DEPLOY_PROD_COMPOSE_FILE=/opt/kbcrm/test-prod/repo/docker-compose.prod.yaml +DEPLOY_PROD_ENV_FILE=/opt/kbcrm/prod/.env +DEPLOY_PROD_PROJECT_NAME=kbpprod +DEPLOY_PROD_TEST_PROJECT_NAME=kbptest +DEPLOY_PROD_HEALTH_PORT=443 +``` + +Wenn `deploy.env` fehlt, verwenden die Scripts ihre eingebauten Defaults +(die den obigen Werten entsprechen). Die `deploy.env` ist nur noetig, wenn +Ihre Verzeichnisstruktur oder Ports abweichen. --- @@ -291,7 +345,7 @@ Das Script fuehrt folgende Schritte aus: Build und Python mit Anwendungscode) 3. Health-Check -### 6.2. Manuelle Promotion nach Prod +### 6.2. Manuelle Promotion nach Prod (Image-Promotion) Nach Verifikation auf dem Test-Server: @@ -299,8 +353,22 @@ Nach Verifikation auf dem Test-Server: /opt/kbcrm/scripts/deploy-kbcrm-prod.sh ``` -Das Script fragt eine Bestaetigung ("yes/no") und fuehrt dann den gleichen -Ablauf aus wie das Test-Script, jedoch mit der Prod-`.env`. +Das Script fragt eine Bestaetigung ("yes/no") und uebernimmt dann die +getesteten Images aus test-prod per `docker tag` — kein Rebuild, kein git pull. +Prod startet mit exakt dem Stand, der in test-prod verifiziert wurde. Nur +die `.env` unterscheidet sich (Ports, Zertifikate, DB-Pfad, OIDC). + +Ablauf: +1. Sicherheitsabfrage ("yes/no") +2. `docker tag` — Images von `kbptest-*` nach `kbpprod-*` kopieren +3. `docker compose up -d` — Container starten (ohne `--build`) +4. Health-Check + +**Wichtig:** Das Prod-Script fuehrt kein `git pull` aus. Eine Aenderung an +der `docker-compose.prod.yaml` zwischen test-prod und Promotion wuerde +bedeuten, dass prod mit einer anderen Konfiguration startet als verifiziert. +Bei Aenderungen an der Compose-Datei muss erst ein neues test-prod-Deploy +durchgefuehrt werden. ### 6.3. Alternative: Git-Tag-basierte Promotion @@ -334,34 +402,34 @@ done ```bash # Test-Prod -docker compose --env-file /opt/kbcrm/test-prod/.env \ +docker compose -p kbptest --env-file /opt/kbcrm/test-prod/.env \ -f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs # Prod -docker compose --env-file /opt/kbcrm/prod/.env \ - -f /opt/kbcrm/prod/repo/docker-compose.prod.yaml logs +docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \ + -f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs # Nur Python-Container -docker compose --env-file /opt/kbcrm/prod/.env \ - -f /opt/kbcrm/prod/repo/docker-compose.prod.yaml logs pythonapp +docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \ + -f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs pythonapp # Nur NGINX-Container -docker compose --env-file /opt/kbcrm/prod/.env \ - -f /opt/kbcrm/prod/repo/docker-compose.prod.yaml logs nginx-proxy +docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \ + -f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs nginx-proxy ``` ### Container-Status pruefen ```bash -docker compose --env-file /opt/kbcrm/prod/.env \ - -f /opt/kbcrm/prod/repo/docker-compose.prod.yaml ps +docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \ + -f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml ps ``` ### Manuell in den Container wechseln ```bash -docker compose --env-file /opt/kbcrm/prod/.env \ - -f /opt/kbcrm/prod/repo/docker-compose.prod.yaml exec pythonapp bash +docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \ + -f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml exec pythonapp bash ``` ### Rollback @@ -370,10 +438,10 @@ Bei Problemen kann auf einen frueheren Stand zurueckgekehrt werden: ```bash # Auf dem Deploy-Server: -cd /opt/kbcrm/prod/repo +cd /opt/kbcrm/test-prod/repo git log --oneline -10 # frueheren Commit finden git checkout -docker compose --env-file /opt/kbcrm/prod/.env \ +docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \ -f docker-compose.prod.yaml up -d --build ``` @@ -425,6 +493,7 @@ docker image prune -f - [ ] Datenbank-Verzeichnisse erstellt (`PYTHON_DB_DIR`) - [ ] SSL-Zertifikate abgelegt (`NGINX_CERTS`) - [ ] Deploy-Scripts kopiert und ausfuehrbar gemacht +- [ ] `deploy.env` angelegt und angepasst (Pfade, Ports, Projekt-Namen) - [ ] Git-Hook oder Webhook eingerichtet (fuer automatisches Test-Deploy) - [ ] Erster manueller Deploy-Test: `deploy-kbcrm-test.sh` - [ ] Health-Check erfolgreich: `curl -k https://localhost:8443/health-check` diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml index 1d1d80a..3e96452 100644 --- a/docker-compose.prod.yaml +++ b/docker-compose.prod.yaml @@ -1,4 +1,6 @@ -name: kbpprod +# Kein name:-Feld — Projekt-Name wird per -p in den Deploy-Scripts gesetzt +# (kbptest fuer test-prod, kbpprod fuer prod), damit beide Umgebungen +# parallel auf dem gleichen Server laufen koennen. services: pythonapp: extends: diff --git a/scripts/deploy-kbcrm-prod.sh b/scripts/deploy-kbcrm-prod.sh old mode 100644 new mode 100755 index 07b236b..79cad07 --- a/scripts/deploy-kbcrm-prod.sh +++ b/scripts/deploy-kbcrm-prod.sh @@ -1,14 +1,45 @@ #!/bin/bash # Deploy-Script: Promotion nach PROD (manuelles OK erforderlich) # Wird manuell aufgerufen, nachdem test-prod verifiziert wurde. +# Uebernimmt die getesteten Images aus test-prod per docker tag (kein Rebuild, +# kein git pull). Die Compose-Datei und .env werden nicht aktualisiert — +# prod startet mit exakt dem Stand, der in test-prod verifiziert wurde. # Voraussetzungen auf dem Server: git, docker, docker compose. +# +# Server-spezifische Konfiguration (Pfade, Ports, Projekt-Namen) wird aus +# einer Datei deploy.env geladen, die im gleichen Verzeichnis wie dieses +# Script liegen muss. Diese Datei ist NICHT Teil des Repos und wird nicht +# per git pull ueberschrieben. Die Defaults unten greifen, falls deploy.env +# fehlt oder einzelne Werte nicht setzt. set -euo pipefail -# Konfiguration — an die jeweilige Server-Umgebung anpassen -REPO_DIR=/opt/kbcrm-prod/repo -COMPOSE_FILE=docker-compose.prod.yaml -ENV_FILE=/opt/kbcrm-prod/.env -PROD_PORT=443 +# === Script-Verzeichnis ermitteln (fuer deploy.env) === +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# === Server-Konfiguration laden (ausserhalb des Repos, nicht per git pull ueberschreibbar) === +DEPLOY_CONFIG="$SCRIPT_DIR/deploy.env" +if [ -f "$DEPLOY_CONFIG" ]; then + source "$DEPLOY_CONFIG" +fi + +# === Defaults — werden verwendet, falls deploy.env fehlt oder Werte nicht setzt === +# COMPOSE_FILE verweist auf das test-prod-Repo — die Compose-Datei wurde +# dort verifiziert und soll in prod identisch sein. Prod hat kein eigenes Repo. +COMPOSE_FILE="${DEPLOY_PROD_COMPOSE_FILE:-/opt/kbcrm/test-prod/repo/docker-compose.prod.yaml}" +ENV_FILE="${DEPLOY_PROD_ENV_FILE:-/opt/kbcrm/prod/.env}" +PROJECT_NAME="${DEPLOY_PROD_PROJECT_NAME:-kbpprod}" +TEST_PROJECT_NAME="${DEPLOY_PROD_TEST_PROJECT_NAME:-kbptest}" +HEALTH_PORT="${DEPLOY_PROD_HEALTH_PORT:-443}" + +# === NGINX_SERVER_NAME aus .env laden (fuer Health-Check Host-Header) === +# Die .env wird per --env-file an Docker Compose uebergeben, aber die Variablen +# stehen nicht als Shell-Variablen im Script zur Verfuegung. Daher laden wir +# NGINX_SERVER_NAME manuell, damit der Health-Check den richtigen Host-Header +# sendet (sonst liefert NGINX 404 wegen server_name-Mismatch). +NGINX_SERVER_NAME="" +if [ -f "$ENV_FILE" ]; then + NGINX_SERVER_NAME=$(grep -E "^NGINX_SERVER_NAME=" "$ENV_FILE" | cut -d= -f2- | tr -d '\r\n') +fi echo "=== Deploy KB-CRM PROD ===" @@ -20,25 +51,29 @@ if [ "$confirmation" != "yes" ]; then exit 1 fi -# 1. Code aktualisieren -cd "$REPO_DIR" -echo "=== Pulling latest code ===" -git fetch origin main -git checkout main -git reset --hard origin/main +# 1. Getestete Images aus test-prod uebernehmen (kein Rebuild, kein git pull) +# docker tag erzeugt eine zusaetzliche Referenz auf das gleiche Image — +# die Original-Tags (kbptest-*) bleiben unangetastet. +echo "=== Promoting tested images from test-prod to prod ===" +docker tag "${TEST_PROJECT_NAME}-pythonapp" "${PROJECT_NAME}-pythonapp" +docker tag "${TEST_PROJECT_NAME}-nginx-proxy" "${PROJECT_NAME}-nginx-proxy" -# 2. Images neu bauen und Container starten -echo "=== Building and starting containers ===" -docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d --build +# 2. Container starten (ohne --build — Images wurden per tag uebernommen) +# -p setzt den Projekt-Namen (fuer Container-Namen) +# --env-file laedt die Container-Variablen (Ports, Zertifikate, DB, OIDC) +# -f gibt die Compose-Datei explizit an (ignoriert COMPOSE_FILE aus .env) +echo "=== Starting prod containers ===" +docker compose -p "$PROJECT_NAME" --env-file "$ENV_FILE" \ + -f "$COMPOSE_FILE" up -d # 3. Health-Check echo "=== Waiting for container startup ===" sleep 10 -if curl -sf "http://localhost:${PROD_PORT}/health-check" >/dev/null 2>&1; then +if curl -sf -H "Host: ${NGINX_SERVER_NAME}" "http://localhost:${HEALTH_PORT}/xhr/health-check" >/dev/null 2>&1; then echo "Health check: OK" else echo "WARNING: Health check failed — check container logs with:" - echo " docker compose --env-file $ENV_FILE -f $COMPOSE_FILE logs" + echo " docker compose -p $PROJECT_NAME --env-file $ENV_FILE -f $COMPOSE_FILE logs" fi echo "=== Deploy PROD complete ===" diff --git a/scripts/deploy-kbcrm-test.sh b/scripts/deploy-kbcrm-test.sh old mode 100644 new mode 100755 index 9a5e148..80cdda0 --- a/scripts/deploy-kbcrm-test.sh +++ b/scripts/deploy-kbcrm-test.sh @@ -2,13 +2,39 @@ # Deploy-Script: Automatisches Deployment nach TEST (test-prod) # Wird durch Git-Hook/Webhook oder manuell aufgerufen. # Voraussetzungen auf dem Server: git, docker, docker compose. +# +# Server-spezifische Konfiguration (Pfade, Ports, Projekt-Namen) wird aus +# einer Datei deploy.env geladen, die im gleichen Verzeichnis wie dieses +# Script liegen muss. Diese Datei ist NICHT Teil des Repos und wird nicht +# per git pull ueberschrieben. Die Defaults unten greifen, falls deploy.env +# fehlt oder einzelne Werte nicht setzt. set -euo pipefail -# Konfiguration — an die jeweilige Server-Umgebung anpassen -REPO_DIR=/opt/kbcrm-test/repo +# === Script-Verzeichnis ermitteln (fuer deploy.env) === +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# === Server-Konfiguration laden (ausserhalb des Repos, nicht per git pull ueberschreibbar) === +DEPLOY_CONFIG="$SCRIPT_DIR/deploy.env" +if [ -f "$DEPLOY_CONFIG" ]; then + source "$DEPLOY_CONFIG" +fi + +# === Defaults — werden verwendet, falls deploy.env fehlt oder Werte nicht setzt === +REPO_DIR="${DEPLOY_REPO_DIR:-/opt/kbcrm/test-prod/repo}" COMPOSE_FILE=docker-compose.prod.yaml -ENV_FILE=/opt/kbcrm-test/.env -TEST_PORT=8443 +ENV_FILE="${DEPLOY_ENV_FILE:-/opt/kbcrm/test-prod/.env}" +PROJECT_NAME="${DEPLOY_PROJECT_NAME:-kbptest}" +HEALTH_PORT="${DEPLOY_HEALTH_PORT:-8443}" + +# === NGINX_SERVER_NAME aus .env laden (fuer Health-Check Host-Header) === +# Die .env wird per --env-file an Docker Compose uebergeben, aber die Variablen +# stehen nicht als Shell-Variablen im Script zur Verfuegung. Daher laden wir +# NGINX_SERVER_NAME manuell, damit der Health-Check den richtigen Host-Header +# sendet (sonst liefert NGINX 404 wegen server_name-Mismatch). +NGINX_SERVER_NAME="" +if [ -f "$ENV_FILE" ]; then + NGINX_SERVER_NAME=$(grep -E "^NGINX_SERVER_NAME=" "$ENV_FILE" | cut -d= -f2- | tr -d '\r\n') +fi echo "=== Deploy KB-CRM TEST ===" @@ -20,17 +46,21 @@ git checkout main git reset --hard origin/main # 2. Images neu bauen und Container starten +# -p setzt den Projekt-Namen (fuer Image-Namen und Container-Namen) +# --env-file laedt die Container-Variablen (Ports, Zertifikate, DB, OIDC) +# -f gibt die Compose-Datei explizit an (ignoriert COMPOSE_FILE aus .env) echo "=== Building and starting containers ===" -docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d --build +docker compose -p "$PROJECT_NAME" --env-file "$ENV_FILE" \ + -f "$COMPOSE_FILE" up -d --build # 3. Health-Check echo "=== Waiting for container startup ===" sleep 10 -if curl -sf "http://localhost:${TEST_PORT}/health-check" >/dev/null 2>&1; then +if curl -sf -H "Host: ${NGINX_SERVER_NAME}" "http://localhost:${HEALTH_PORT}/xhr/health-check" >/dev/null 2>&1; then echo "Health check: OK" else echo "WARNING: Health check failed — check container logs with:" - echo " docker compose --env-file $ENV_FILE -f $COMPOSE_FILE logs" + echo " docker compose -p $PROJECT_NAME --env-file $ENV_FILE -f $COMPOSE_FILE logs" fi echo "=== Deploy TEST complete ===" diff --git a/scripts/deploy.env.example b/scripts/deploy.env.example new file mode 100644 index 0000000..70d3cb5 --- /dev/null +++ b/scripts/deploy.env.example @@ -0,0 +1,23 @@ +# ============================================================================= +# deploy.env — Server-spezifische Konfiguration fuer die Deploy-Scripts +# ============================================================================= +# Diese Datei liegt NICHT im Git-Repo und wird NICHT per git pull ueberschrieben. +# Kopieren Sie diese Vorlage nach deploy.env (im gleichen Verzeichnis wie die +# Scripts) und passen Sie die Werte an Ihre Server-Umgebung an. +# +# Wenn deploy.env fehlt, verwenden die Scripts ihre eingebauten Defaults. +# ============================================================================= + +# --- Test-Prod Umgebung (fuer deploy-kbcrm-test.sh) --- +DEPLOY_REPO_DIR=/opt/kbcrm/test-prod/repo +DEPLOY_ENV_FILE=/opt/kbcrm/test-prod/.env +DEPLOY_PROJECT_NAME=kbptest +DEPLOY_HEALTH_PORT=8443 + +# --- Prod Umgebung (fuer deploy-kbcrm-prod.sh) --- +# COMPOSE_FILE muss auf das test-prod-Repo verweisen (prod hat kein eigenes Repo) +DEPLOY_PROD_COMPOSE_FILE=/opt/kbcrm/test-prod/repo/docker-compose.prod.yaml +DEPLOY_PROD_ENV_FILE=/opt/kbcrm/prod/.env +DEPLOY_PROD_PROJECT_NAME=kbpprod +DEPLOY_PROD_TEST_PROJECT_NAME=kbptest +DEPLOY_PROD_HEALTH_PORT=443