ARG-Variablen durch feste Werte in FROM ersetzt — nicht per .env ueberschreibbar. PYTHON_VERSION, NODE_VERSION, NPM_VERSION, NGINX_VERSION aus .env, env-sample und Compose-Dateien entfernt. Deployment-Anleitung erstellt und entsprechend angepasst. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
12 KiB
Anleitung: Automatisches Deployment einrichten
Diese Anleitung richtet sich an den Administrator des Deploy-Servers. Sie beschreibt, wie der automatische Deploy-Mechanismus fuer KB-CRM eingerichtet und betrieben wird.
1. Architektur ueberblick
Entwickler
│ git push origin main
▼
┌─────────────────┐
│ Git-Remote │ (z.B. Gitea auf git.everdc.eu)
└────────┬────────┘
│ Webhook oder post-receive Hook
▼
┌─────────────────┐
│ Deploy-Server │
│ (Deploy-Script) │
└────────┬────────┘
│
┌──────────┴──────────┐
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Stufe 1: TEST │ │ Stufe 2: PROD │
│ (automatisch) │ │ (manuell) │
└─────────────────┘ └─────────────────┘
Prinzip:
- Jeder
git pushaufmainloest automatisch ein Deployment auf dem Test-Server aus (Stufe 1). - Nach erfolgreicher Verifikation wird manuell auf den Prod-Server deployt (Stufe 2).
- In Prod wird der gesamte Code (Python + TypeScript) in das Docker-Image gebaut. Es wird kein Node.js, npm oder Python-venv auf dem Server benoetigt.
- Der Deploy-Server benoetigt nur:
git,dockerunddocker compose.
2. Voraussetzungen auf dem Deploy-Server
Folgende Software muss installiert sein:
| Software | Version | Zweck |
|---|---|---|
git |
aktuell | Code vom Remote-Repository holen |
docker |
aktuell | Container bauen und starten |
docker compose |
v2+ | Multi-Container-Orchestrierung |
curl |
aktuell | Health-Check nach Deploy |
Docker Compose muss als Plugin installiert sein (Befehl: docker compose,
nicht docker-compose).
3. Verzeichnisstruktur auf dem Deploy-Server
Es werden zwei Umgebungen (test-prod und prod) parallel betrieben:
/opt/kbcrm/
├── test-prod/
│ ├── repo/ ← git clone des Repos
│ └── .env ← test-prod Umgebung (eigene Ports, eigene DB)
├── prod/
│ ├── repo/
│ └── .env ← prod Umgebung
└── scripts/
├── deploy-kbcrm-test.sh ← aus dem Repo (scripts/)
└── deploy-kbcrm-prod.sh ← aus dem Repo (scripts/)
Die SQLite-Datenbanken liegen ausserhalb des Repos in einem bind-mount
(PYTHON_DB_DIR), der beim Deploy nicht beruehrt wird.
4. Einrichtung: Schritt fuer Schritt
4.1. Repositories klonen
sudo mkdir -p /opt/kbcrm/test-prod /opt/kbcrm/prod
# Test-Prod Repository
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
4.2. .env-Dateien anlegen
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
4.3. .env fuer Test-Prod anpassen
vi /opt/kbcrm/test-prod/.env
Folgende Einstellungen muessen angepasst werden:
# WICHTIG: BUILD_ENVIRONMENT muss in den .env-Dateien auf dem Deploy-Server
# NICHT gesetzt werden. Die Deploy-Scripts rufen docker compose explizit
# mit -f docker-compose.prod.yaml auf und ignorieren COMPOSE_FILE.
# Daher kann BUILD_ENVIRONMENT und COMPOSE_FILE aus der .env geloescht
# oder ignoriert werden.
# NGINX-Server
NGINX_USE_SSL=true
NGINX_HOST_PORT=8443 # eigener Port fuer Test-Prod
NGINX_SERVER_NAME=test.kbp_crm.mylocal.de
# NGINX_STATIC_DIR und NGINX_CONFIG_TEMPLATE_DIR werden in Prod nicht
# benoetigt (statische Dateien und Templates sind im Image).
NGINX_CERTS=/opt/kbcrm/test-prod/certs # Pfad zu SSL-Zertifikaten
NGINX_CERT=test-wildcard.mylocal.crt
NGINX_CERT_KEY=test-wildcard.mylocal.key
# Python App-Server
PYTHON_DB_DIR=/opt/kbcrm/test-prod/data # eigene DB fuer Test-Prod
# OIDC-Settings anpassen (ggf. separater OIDC-Client fuer Test)
ZITADEL_ISSUER=https://id.vmlx.de
ZITADEL_CLIENT_ID=<test-client-id>
ZITADEL_CLIENT_SECRET=<test-client-secret>
ZITADEL_REDIRECT_URI=https://test.kbp_crm.mylocal.de/auth/callback
4.4. .env fuer Prod anpassen
vi /opt/kbcrm/prod/.env
NGINX_HOST_PORT=443 # Produktions-Port
NGINX_SERVER_NAME=kbp_crm.mylocal.de
NGINX_CERTS=/opt/kbcrm/prod/certs
NGINX_CERT=wildcard.mylocal.crt
NGINX_CERT_KEY=wildcard.mylocal.key
PYTHON_DB_DIR=/opt/kbcrm/prod/data # eigene DB fuer Prod
ZITADEL_REDIRECT_URI=https://kbp_crm.mylocal.de/auth/callback
4.5. Datenbank-Verzeichnisse erstellen
sudo mkdir -p /opt/kbcrm/test-prod/data
sudo mkdir -p /opt/kbcrm/prod/data
4.6. SSL-Zertifikate ablegen
Kopieren Sie die Zertifikate in die in .env angegebenen Verzeichnisse:
sudo mkdir -p /opt/kbcrm/test-prod/certs /opt/kbcrm/prod/certs
sudo cp wildcard.mylocal.crt wildcard.mylocal.key /opt/kbcrm/test-prod/certs/
sudo cp wildcard.mylocal.crt wildcard.mylocal.key /opt/kbcrm/prod/certs/
4.7. Deploy-Scripts kopieren
Die Scripts liegen im Repo unter scripts/. Kopieren Sie sie an einen
zentralen Ort:
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 chmod +x /opt/kbcrm/scripts/*.sh
Passen Sie die Pfad-Variablen am Anfang der Scripts an, falls Ihre Verzeichnisstruktur abweicht.
5. Git-Hook einrichten (automatisches Test-Deploy)
Variante A: post-receive Hook (direkt auf dem Git-Server)
Wenn Shell-Zugang zum Git-Server besteht:
# Auf dem Git-Server, im bare Repository:
vi /srv/git/kbcrm.git/hooks/post-receive
#!/bin/bash
while read oldrev newrev ref; do
if [ "$ref" = "refs/heads/main" ]; then
ssh deploy-user@deploy-server "/opt/kbcrm/scripts/deploy-kbcrm-test.sh"
fi
done
chmod +x /srv/git/kbcrm.git/hooks/post-receive
Variante B: Webhook (empfohlen fuer Gitea)
- In Gitea: Repository-Einstellungen -> Webhooks -> Webhook hinzufuegen
- URL:
http://deploy-server:9000/webhook(Beispiel) - Content-Type:
application/json - Trigger: "Push Events" (nur auf
main) - Auf dem Deploy-Server: kleiner HTTP-Listener, der den Webhook entgegennimmt und das Deploy-Script startet.
Beispiel fuer einen einfachen Webhook-Listener (systemd-Service mit Python):
# /opt/kbcrm/scripts/webhook-listener.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import subprocess
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
subprocess.run(["/opt/kbcrm/scripts/deploy-kbcrm-test.sh"])
self.send_response(200)
self.end_headers()
HTTPServer(("", 9000), Handler).serve_forever()
Systemd-Service:
# /etc/systemd/system/kbcrm-webhook.service
[Unit]
Description=KB-CRM Deploy Webhook Listener
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/kbcrm/scripts/webhook-listener.py
Restart=always
User=deploy-user
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now kbcrm-webhook
6. Deployment durchfuehren
6.1. Automatisches Deploy nach Test-Prod
Wird durch git push ausgeloest (sofern Hook eingerichtet). Manuell:
/opt/kbcrm/scripts/deploy-kbcrm-test.sh
Das Script fuehrt folgende Schritte aus:
git pull(latest main)docker compose up -d --build(baut beide Images: NGINX mit TypeScript- Build und Python mit Anwendungscode)- Health-Check
6.2. Manuelle Promotion nach Prod
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.
6.3. Alternative: Git-Tag-basierte Promotion
Statt das Prod-Script manuell aufzurufen, kann ein Git-Tag das Prod-Deploy ausloesen:
# Auf dem Entwickler-Rechner:
git tag -a v00.00.02 -m "Release: deploy to prod"
git push origin v00.00.02
Der post-receive-Hook prueft auf Tags:
#!/bin/bash
while read oldrev newrev ref; do
if [ "$ref" = "refs/heads/main" ]; then
ssh deploy-user@deploy-server "/opt/kbcrm/scripts/deploy-kbcrm-test.sh"
elif [[ "$ref" = refs/tags/v* ]]; then
ssh deploy-user@deploy-server "/opt/kbcrm/scripts/deploy-kbcrm-prod.sh"
fi
done
7. Wartung und Fehlersuche
Logs anzeigen
# Test-Prod
docker compose --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
# Nur Python-Container
docker compose --env-file /opt/kbcrm/prod/.env \
-f /opt/kbcrm/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
Container-Status pruefen
docker compose --env-file /opt/kbcrm/prod/.env \
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml ps
Manuell in den Container wechseln
docker compose --env-file /opt/kbcrm/prod/.env \
-f /opt/kbcrm/prod/repo/docker-compose.prod.yaml exec pythonapp bash
Rollback
Bei Problemen kann auf einen frueheren Stand zurueckgekehrt werden:
# Auf dem Deploy-Server:
cd /opt/kbcrm/prod/repo
git log --oneline -10 # frueheren Commit finden
git checkout <commit-hash>
docker compose --env-file /opt/kbcrm/prod/.env \
-f docker-compose.prod.yaml up -d --build
Datenbank sichern
Die SQLite-Datenbanken liegen im bind-mount (PYTHON_DB_DIR).
Sicherung:
cp /opt/kbcrm/prod/data/*.db /backup/kbcrm-prod-$(date +%Y%m%d).db
Docker-Images aufraeumen
Nach mehreren Deploys koennen alte Images Speicher belegen:
docker image prune -f
8. Uebersicht: .env-Variablen fuer Prod
| Variable | Erforderlich | Beschreibung |
|---|---|---|
NGINX_USE_SSL |
ja | SSL aktivieren (true/false) |
NGINX_HOST_PORT |
ja | Externer Port (443 fuer SSL, 8080 fuer no-SSL) |
NGINX_SERVER_NAME |
ja | Server-Name fuer NGINX-Konfiguration |
NGINX_CERTS |
ja | Pfad zu SSL-Zertifikaten (bind-mount) |
NGINX_CERT |
ja | Zertifikatsdatei |
NGINX_CERT_KEY |
ja | Privater Schluessel |
NGINX_STATIC_DIR |
nein | Nur in Dev; in Prod im Image |
NGINX_CONFIG_TEMPLATE_DIR |
nein | Nur in Dev; in Prod im Image |
PYTHON_DB_DIR |
ja | Pfad zu SQLite-Datenbanken (bind-mount) |
PYTHON_DEV_DIR |
nein | Nur in Dev |
APP_DEBUG |
nein | Nur in Dev; in Prod nicht setzen |
BUILD_ENVIRONMENT |
nein | Nicht relevant — Deploy-Scripts geben Compose-Datei explizit an. In .env auf Deploy-Server nicht erforderlich |
ZITADEL_* |
ja | OIDC-Konfiguration |
COMPOSE_FILE |
nein | Wird von Deploy-Scripts ignoriert |
9. Checkliste fuer den Admin
- Docker und Docker Compose installiert
- Git installiert, Repository geklont (test-prod + prod)
.env-Dateien erstellt und angepasst (Ports, DB, Zertifikate, OIDC)- Datenbank-Verzeichnisse erstellt (
PYTHON_DB_DIR) - SSL-Zertifikate abgelegt (
NGINX_CERTS) - Deploy-Scripts kopiert und ausfuehrbar gemacht
- 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 - Erster Prod-Deploy:
deploy-kbcrm-prod.sh - Health-Check erfolgreich:
curl -k https://localhost:443/health-check