Compare commits
2
Commits
bde45871f6
...
efef212544
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efef212544 | ||
|
|
e824b545bb |
No files matched your search
@@ -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.
|
|
||||||
@@ -5,12 +5,12 @@ In den Programmen sollen aussagekräftige Kommentare in deutsch erstellt werden.
|
|||||||
## Vorgaben git Versionsverwaltung
|
## Vorgaben git Versionsverwaltung
|
||||||
Ein neuer Branch darf nur auf ausdrückliche Anweisung hin erstellt werden. Ohne diese Anweisung werden Änderungen immer in main gemacht.
|
Ein neuer Branch darf nur auf ausdrückliche Anweisung hin erstellt werden. Ohne diese Anweisung werden Änderungen immer in main gemacht.
|
||||||
|
|
||||||
## Vorgaben für die Typescript und mithriljs Entwicklung
|
## Vorgaben für die Typescript und mithril.js Entwicklung
|
||||||
Verwende bei der GUI primar die widgets, die es in client/Components/widgets gibt. Fehler widgets, gib eines Hinweis und erstelle einen Vorschlag für ein entsprechendes neues Widget.
|
Verwende bei der GUI primar die Widgets und Komponenten, die es in Client/Components/widgets und Client/Components gibt. Wenn Widgets fehlen, gib eines Hinweis und erstelle einen Vorschlag für ein entsprechendes neues Widget.
|
||||||
Es soll immer ein responsive Design implmentiert werden, da die App sowohl auf PCs als auch auf mobilen Geräten laufen soll.
|
Es soll immer ein responsive Design implmentiert werden, da die App sowohl auf PCs als auch auf mobilen Geräten laufen soll.
|
||||||
Verwende für Attribute der GUI-Oberfläche nach Möglichkeit Klassen aus NGINX_Server/html/static/w3.css, insbesondere wenn es darum geht, eine Respnosive Design zu implentieren.
|
Verwende für Attribute der GUI-Oberfläche nach Möglichkeit Klassen aus NGINX_Server/html/static/w3.css, insbesondere wenn es darum geht, ein Respnosive Design zu implentieren.
|
||||||
Für Farben (foreground und background) verwende priorisiert die Klassen aus NGINX_Server/html/static/app-theme.css
|
Für Farben (foreground und background) verwende priorisiert die Klassen aus NGINX_Server/html/static/app-theme.css
|
||||||
View-Container werden mit `w3-container.w3-auto` gewrappt, damit sie auf kleinen Bildschirmen 100% und auf großen bis max. 1140px (bzw. 95%) zentriert nutzen.
|
View-Container werden mit `w3-container.w3-auto` gewrappt, damit sie auf kleinen Bildschirmen 100% und auf großen bis max. 1140px (bzw. 95%) zentriert werden.
|
||||||
|
|
||||||
Bei Mithril `m(...)`-Aufrufen mit längeren Attributlisten (z.B. mehrere `style`-Eigenschaften oder mehrere Attribute) schreibe die Attribute untereinander, sobald sie in einer Zeile nicht mehr gut lesbar sind (Faustregel: mehr als 2–3 Attribute oder ein mehrzeiliges `style`-Objekt). Kurze Attributlisten (1–2 Attribute, einzeiliges `style`) dürfen in einer Zeile bleiben. Formatbeispiel:
|
Bei Mithril `m(...)`-Aufrufen mit längeren Attributlisten (z.B. mehrere `style`-Eigenschaften oder mehrere Attribute) schreibe die Attribute untereinander, sobald sie in einer Zeile nicht mehr gut lesbar sind (Faustregel: mehr als 2–3 Attribute oder ein mehrzeiliges `style`-Objekt). Kurze Attributlisten (1–2 Attribute, einzeiliges `style`) dürfen in einer Zeile bleiben. Formatbeispiel:
|
||||||
```typescript
|
```typescript
|
||||||
@@ -25,7 +25,7 @@ m("div.w3-bar-block.w3-border", {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Für Symbole auf Buttons und ähnlichen Steuerelementen verwende Symbole aus den Google Material Icons.
|
Für Symbole auf Buttons und ähnlichen Steuerelementen verwende Symbole aus den Google Material Icons aus der NGINX_Server/html/static/Google_Symbols.woff2 Datei.
|
||||||
Erstelle die Datenmodelle für die Typescript-Entwicklung im Verzeichnis Client/Models. Erstelle für die verschiedenen Datenmodelle (Kunde, Projekt usw.) eigene .ts-Dateien. Erstelle in der jeweiligen Datei auch den Aufruf der REST-Api für die Server-Seite.
|
Erstelle die Datenmodelle für die Typescript-Entwicklung im Verzeichnis Client/Models. Erstelle für die verschiedenen Datenmodelle (Kunde, Projekt usw.) eigene .ts-Dateien. Erstelle in der jeweiligen Datei auch den Aufruf der REST-Api für die Server-Seite.
|
||||||
|
|
||||||
Beim Aufruf einer Bearbeitungsmaske werden in den Route-Params nur die ID (und ggf. zum Vorbelegen notwendige Eltern-FKs wie `kunden_id`) übergeben — nicht die vollständigen Felder des Objekts. Die Maske lädt die Daten frisch vom Server via `fetchXxxById(id)` im `oninit`. So wird sichergestellt, dass die Daten aktuell sind und zwischenzeitliche Änderungen anderer Nutzer nicht mit veralteten Werten aus der Liste überschrieben werden. Beim Neuanlegen (`id === -1`) entfällt der Fetch; vorbelegte Werte (z.B. `kunden_id`) kommen aus den Route-Params.
|
Beim Aufruf einer Bearbeitungsmaske werden in den Route-Params nur die ID (und ggf. zum Vorbelegen notwendige Eltern-FKs wie `kunden_id`) übergeben — nicht die vollständigen Felder des Objekts. Die Maske lädt die Daten frisch vom Server via `fetchXxxById(id)` im `oninit`. So wird sichergestellt, dass die Daten aktuell sind und zwischenzeitliche Änderungen anderer Nutzer nicht mit veralteten Werten aus der Liste überschrieben werden. Beim Neuanlegen (`id === -1`) entfällt der Fetch; vorbelegte Werte (z.B. `kunden_id`) kommen aus den Route-Params.
|
||||||
@@ -64,6 +64,8 @@ Dafür werden in `crm/routes.py` zwei Hilfsfunktionen bereitgestellt:
|
|||||||
- `_get_visible_user_id()`: Liefert `None` für SysAdmin/AppAdmin (kein Filter), sonst `current_user.id`. Wird an die Modell-Funktionen der Lese-Endpunkte (list/get) übergeben.
|
- `_get_visible_user_id()`: Liefert `None` für SysAdmin/AppAdmin (kein Filter), sonst `current_user.id`. Wird an die Modell-Funktionen der Lese-Endpunkte (list/get) übergeben.
|
||||||
- `_require_projekt_access(projekt_id)`: Prüft vor Schreiboperationen (create/update/delete), ob der Nutzer dem Projekt zugeordnet ist. Bei fehlender Zuordnung wird 404 (nicht 403) geworfen, um keine Rückschlüsse auf die Existenz des Projekts zu ermöglichen.
|
- `_require_projekt_access(projekt_id)`: Prüft vor Schreiboperationen (create/update/delete), ob der Nutzer dem Projekt zugeordnet ist. Bei fehlender Zuordnung wird 404 (nicht 403) geworfen, um keine Rückschlüsse auf die Existenz des Projekts zu ermöglichen.
|
||||||
|
|
||||||
|
Die `user_id` wird als Parameter übergeben statt `current_user` direkt im Modell zu lesen, weil `None` als Signalwert für Admins (kein Filter) nur so sauber transportiert werden kann und die Modell-Funktionen frei von Flask-Request-Kontext bleiben — das wahrt die Schichtentrennung und Testbarkeit.
|
||||||
|
|
||||||
Bei neuen projektbezogenen Entitäten muss:
|
Bei neuen projektbezogenen Entitäten muss:
|
||||||
1. Die Modell-Funktion `get_xxx(...)` einen optionalen `user_id`-Parameter erhalten. Ist dieser gesetzt, wird per Subquery auf `projekt_users` gefiltert.
|
1. Die Modell-Funktion `get_xxx(...)` einen optionalen `user_id`-Parameter erhalten. Ist dieser gesetzt, wird per Subquery auf `projekt_users` gefiltert.
|
||||||
2. Die Modell-Funktion `get_xxx_by_id(id, user_id)` bei gesetztem `user_id` die Projekt-Zuordnung prüfen und bei Fehlen 404 werfen.
|
2. Die Modell-Funktion `get_xxx_by_id(id, user_id)` bei gesetztem `user_id` die Projekt-Zuordnung prüfen und bei Fehlen 404 werfen.
|
||||||
|
|||||||
@@ -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 |
|
||||||
@@ -58,6 +58,23 @@ Folgende Software muss installiert sein:
|
|||||||
Docker Compose muss als Plugin installiert sein (Befehl: `docker compose`,
|
Docker Compose muss als Plugin installiert sein (Befehl: `docker compose`,
|
||||||
nicht `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
|
## 3. Verzeichnisstruktur auf dem Deploy-Server
|
||||||
@@ -67,14 +84,14 @@ Es werden zwei Umgebungen (test-prod und prod) parallel betrieben:
|
|||||||
```
|
```
|
||||||
/opt/kbcrm/
|
/opt/kbcrm/
|
||||||
├── test-prod/
|
├── 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)
|
│ └── .env ← test-prod Umgebung (eigene Ports, eigene DB)
|
||||||
├── prod/
|
├── prod/
|
||||||
│ ├── repo/
|
│ └── .env ← prod Umgebung (kein eigenes Repo — Images per docker tag)
|
||||||
│ └── .env ← prod Umgebung
|
|
||||||
└── scripts/
|
└── scripts/
|
||||||
├── deploy-kbcrm-test.sh ← aus dem Repo (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
|
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
|
```bash
|
||||||
sudo mkdir -p /opt/kbcrm/test-prod /opt/kbcrm/prod
|
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
|
sudo git clone https://git.everdc.eu/chmln-app-dev/kbcrm /opt/kbcrm/test-prod/repo
|
||||||
|
|
||||||
# Prod Repository
|
# Falls das Verzeichnis bereits existiert und aktualisiert werden soll:
|
||||||
sudo git clone https://git.everdc.eu/chmln-app-dev/kbcrm /opt/kbcrm/prod/repo
|
# 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
|
### 4.2. `.env`-Dateien anlegen
|
||||||
@@ -104,8 +126,8 @@ Kopieren Sie die Vorlage aus dem Repo und passen Sie die Werte an:
|
|||||||
# Test-Prod
|
# Test-Prod
|
||||||
cp /opt/kbcrm/test-prod/repo/env-sample /opt/kbcrm/test-prod/.env
|
cp /opt/kbcrm/test-prod/repo/env-sample /opt/kbcrm/test-prod/.env
|
||||||
|
|
||||||
# Prod
|
# Prod (Vorlage aus test-prod-Repo)
|
||||||
cp /opt/kbcrm/prod/repo/env-sample /opt/kbcrm/prod/.env
|
cp /opt/kbcrm/test-prod/repo/env-sample /opt/kbcrm/prod/.env
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.3. `.env` fuer Test-Prod anpassen
|
### 4.3. `.env` fuer Test-Prod anpassen
|
||||||
@@ -194,12 +216,44 @@ zentralen Ort:
|
|||||||
```bash
|
```bash
|
||||||
sudo mkdir -p /opt/kbcrm/scripts
|
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/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
|
sudo chmod +x /opt/kbcrm/scripts/*.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Passen Sie die Pfad-Variablen am Anfang der Scripts an, falls Ihre
|
### 4.8. `deploy.env` anlegen (Server-spezifische Konfiguration)
|
||||||
Verzeichnisstruktur abweicht.
|
|
||||||
|
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)
|
Build und Python mit Anwendungscode)
|
||||||
3. Health-Check
|
3. Health-Check
|
||||||
|
|
||||||
### 6.2. Manuelle Promotion nach Prod
|
### 6.2. Manuelle Promotion nach Prod (Image-Promotion)
|
||||||
|
|
||||||
Nach Verifikation auf dem Test-Server:
|
Nach Verifikation auf dem Test-Server:
|
||||||
|
|
||||||
@@ -299,8 +353,22 @@ Nach Verifikation auf dem Test-Server:
|
|||||||
/opt/kbcrm/scripts/deploy-kbcrm-prod.sh
|
/opt/kbcrm/scripts/deploy-kbcrm-prod.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Das Script fragt eine Bestaetigung ("yes/no") und fuehrt dann den gleichen
|
Das Script fragt eine Bestaetigung ("yes/no") und uebernimmt dann die
|
||||||
Ablauf aus wie das Test-Script, jedoch mit der Prod-`.env`.
|
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
|
### 6.3. Alternative: Git-Tag-basierte Promotion
|
||||||
|
|
||||||
@@ -334,34 +402,34 @@ done
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Test-Prod
|
# 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
|
-f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs
|
||||||
|
|
||||||
# Prod
|
# Prod
|
||||||
docker compose --env-file /opt/kbcrm/prod/.env \
|
docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \
|
||||||
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml logs
|
-f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs
|
||||||
|
|
||||||
# Nur Python-Container
|
# Nur Python-Container
|
||||||
docker compose --env-file /opt/kbcrm/prod/.env \
|
docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \
|
||||||
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml logs pythonapp
|
-f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs pythonapp
|
||||||
|
|
||||||
# Nur NGINX-Container
|
# Nur NGINX-Container
|
||||||
docker compose --env-file /opt/kbcrm/prod/.env \
|
docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \
|
||||||
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml logs nginx-proxy
|
-f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml logs nginx-proxy
|
||||||
```
|
```
|
||||||
|
|
||||||
### Container-Status pruefen
|
### Container-Status pruefen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --env-file /opt/kbcrm/prod/.env \
|
docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \
|
||||||
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml ps
|
-f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml ps
|
||||||
```
|
```
|
||||||
|
|
||||||
### Manuell in den Container wechseln
|
### Manuell in den Container wechseln
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --env-file /opt/kbcrm/prod/.env \
|
docker compose -p kbpprod --env-file /opt/kbcrm/prod/.env \
|
||||||
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml exec pythonapp bash
|
-f /opt/kbcrm/test-prod/repo/docker-compose.prod.yaml exec pythonapp bash
|
||||||
```
|
```
|
||||||
|
|
||||||
### Rollback
|
### Rollback
|
||||||
@@ -370,10 +438,10 @@ Bei Problemen kann auf einen frueheren Stand zurueckgekehrt werden:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Auf dem Deploy-Server:
|
# Auf dem Deploy-Server:
|
||||||
cd /opt/kbcrm/prod/repo
|
cd /opt/kbcrm/test-prod/repo
|
||||||
git log --oneline -10 # frueheren Commit finden
|
git log --oneline -10 # frueheren Commit finden
|
||||||
git checkout <commit-hash>
|
git checkout <commit-hash>
|
||||||
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
|
-f docker-compose.prod.yaml up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -425,6 +493,7 @@ docker image prune -f
|
|||||||
- [ ] Datenbank-Verzeichnisse erstellt (`PYTHON_DB_DIR`)
|
- [ ] Datenbank-Verzeichnisse erstellt (`PYTHON_DB_DIR`)
|
||||||
- [ ] SSL-Zertifikate abgelegt (`NGINX_CERTS`)
|
- [ ] SSL-Zertifikate abgelegt (`NGINX_CERTS`)
|
||||||
- [ ] Deploy-Scripts kopiert und ausfuehrbar gemacht
|
- [ ] Deploy-Scripts kopiert und ausfuehrbar gemacht
|
||||||
|
- [ ] `deploy.env` angelegt und angepasst (Pfade, Ports, Projekt-Namen)
|
||||||
- [ ] Git-Hook oder Webhook eingerichtet (fuer automatisches Test-Deploy)
|
- [ ] Git-Hook oder Webhook eingerichtet (fuer automatisches Test-Deploy)
|
||||||
- [ ] Erster manueller Deploy-Test: `deploy-kbcrm-test.sh`
|
- [ ] Erster manueller Deploy-Test: `deploy-kbcrm-test.sh`
|
||||||
- [ ] Health-Check erfolgreich: `curl -k https://localhost:8443/health-check`
|
- [ ] Health-Check erfolgreich: `curl -k https://localhost:8443/health-check`
|
||||||
|
|||||||
@@ -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:
|
services:
|
||||||
pythonapp:
|
pythonapp:
|
||||||
extends:
|
extends:
|
||||||
|
|||||||
Regular → Executable
+51
-16
@@ -1,14 +1,45 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Deploy-Script: Promotion nach PROD (manuelles OK erforderlich)
|
# Deploy-Script: Promotion nach PROD (manuelles OK erforderlich)
|
||||||
# Wird manuell aufgerufen, nachdem test-prod verifiziert wurde.
|
# 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.
|
# 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
|
set -euo pipefail
|
||||||
|
|
||||||
# Konfiguration — an die jeweilige Server-Umgebung anpassen
|
# === Script-Verzeichnis ermitteln (fuer deploy.env) ===
|
||||||
REPO_DIR=/opt/kbcrm-prod/repo
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
COMPOSE_FILE=docker-compose.prod.yaml
|
|
||||||
ENV_FILE=/opt/kbcrm-prod/.env
|
# === Server-Konfiguration laden (ausserhalb des Repos, nicht per git pull ueberschreibbar) ===
|
||||||
PROD_PORT=443
|
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 ==="
|
echo "=== Deploy KB-CRM PROD ==="
|
||||||
|
|
||||||
@@ -20,25 +51,29 @@ if [ "$confirmation" != "yes" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 1. Code aktualisieren
|
# 1. Getestete Images aus test-prod uebernehmen (kein Rebuild, kein git pull)
|
||||||
cd "$REPO_DIR"
|
# docker tag erzeugt eine zusaetzliche Referenz auf das gleiche Image —
|
||||||
echo "=== Pulling latest code ==="
|
# die Original-Tags (kbptest-*) bleiben unangetastet.
|
||||||
git fetch origin main
|
echo "=== Promoting tested images from test-prod to prod ==="
|
||||||
git checkout main
|
docker tag "${TEST_PROJECT_NAME}-pythonapp" "${PROJECT_NAME}-pythonapp"
|
||||||
git reset --hard origin/main
|
docker tag "${TEST_PROJECT_NAME}-nginx-proxy" "${PROJECT_NAME}-nginx-proxy"
|
||||||
|
|
||||||
# 2. Images neu bauen und Container starten
|
# 2. Container starten (ohne --build — Images wurden per tag uebernommen)
|
||||||
echo "=== Building and starting containers ==="
|
# -p setzt den Projekt-Namen (fuer Container-Namen)
|
||||||
docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d --build
|
# --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
|
# 3. Health-Check
|
||||||
echo "=== Waiting for container startup ==="
|
echo "=== Waiting for container startup ==="
|
||||||
sleep 10
|
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"
|
echo "Health check: OK"
|
||||||
else
|
else
|
||||||
echo "WARNING: Health check failed — check container logs with:"
|
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
|
fi
|
||||||
|
|
||||||
echo "=== Deploy PROD complete ==="
|
echo "=== Deploy PROD complete ==="
|
||||||
Regular → Executable
+37
-7
@@ -2,13 +2,39 @@
|
|||||||
# Deploy-Script: Automatisches Deployment nach TEST (test-prod)
|
# Deploy-Script: Automatisches Deployment nach TEST (test-prod)
|
||||||
# Wird durch Git-Hook/Webhook oder manuell aufgerufen.
|
# Wird durch Git-Hook/Webhook oder manuell aufgerufen.
|
||||||
# Voraussetzungen auf dem Server: git, docker, docker compose.
|
# 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
|
set -euo pipefail
|
||||||
|
|
||||||
# Konfiguration — an die jeweilige Server-Umgebung anpassen
|
# === Script-Verzeichnis ermitteln (fuer deploy.env) ===
|
||||||
REPO_DIR=/opt/kbcrm-test/repo
|
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
|
COMPOSE_FILE=docker-compose.prod.yaml
|
||||||
ENV_FILE=/opt/kbcrm-test/.env
|
ENV_FILE="${DEPLOY_ENV_FILE:-/opt/kbcrm/test-prod/.env}"
|
||||||
TEST_PORT=8443
|
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 ==="
|
echo "=== Deploy KB-CRM TEST ==="
|
||||||
|
|
||||||
@@ -20,17 +46,21 @@ git checkout main
|
|||||||
git reset --hard origin/main
|
git reset --hard origin/main
|
||||||
|
|
||||||
# 2. Images neu bauen und Container starten
|
# 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 ==="
|
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
|
# 3. Health-Check
|
||||||
echo "=== Waiting for container startup ==="
|
echo "=== Waiting for container startup ==="
|
||||||
sleep 10
|
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"
|
echo "Health check: OK"
|
||||||
else
|
else
|
||||||
echo "WARNING: Health check failed — check container logs with:"
|
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
|
fi
|
||||||
|
|
||||||
echo "=== Deploy TEST complete ==="
|
echo "=== Deploy TEST complete ==="
|
||||||
@@ -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
|
||||||
Reference in new issue
Block a user