Refactor deployment process and update documentation
- Removed nginx configuration file as it is no longer needed. - Updated README.md to reflect changes in deployment structure. - Enhanced DEPLOYMENT.md with detailed directory structure and user permissions. - Added release.sh and rollback.sh scripts for managing deployments. - Improved N8N.md to clarify file access and document handling. - Adjusted health check and cache flushing procedures in deployment scripts.
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Eine hochgeladene Veröffentlichung aktivieren.
|
||||
#
|
||||
# Läuft auf dem Webserver als Benutzer `deploy`. Die Gitea-Strecke ruft das Skript
|
||||
# nach dem Hochladen auf; von Hand geht es genauso:
|
||||
#
|
||||
# /var/www/ekdos/deploy/release.sh 2f9c1ab
|
||||
#
|
||||
# Erwartete Verzeichnisse:
|
||||
#
|
||||
# $ROOT/releases/<name>/public das Vite-Bündel
|
||||
# $ROOT/releases/<name>/backend das PHP-Backend (noch ohne vendor/)
|
||||
# $ROOT/shared/.env die Konfiguration, überlebt jedes Ausrollen
|
||||
# $ROOT/current -> releases/<name> der Symlink, den nginx liest
|
||||
#
|
||||
# Beide Hälften werden mit einem einzigen Symlink-Tausch gemeinsam sichtbar.
|
||||
# Schlägt vorher etwas fehl, bricht das Skript ab und die laufende Fassung
|
||||
# bleibt unberührt.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="${EKDOS_ROOT:-/var/www/ekdos}"
|
||||
KEEP="${EKDOS_KEEP:-5}"
|
||||
FPM_SERVICE="${EKDOS_FPM:-php8.5-fpm}"
|
||||
HEALTH_URL="${EKDOS_HEALTH_URL:-http://127.0.0.1/api/health}"
|
||||
|
||||
RELEASE="${1:-}"
|
||||
[ -n "$RELEASE" ] || { echo "Aufruf: release.sh <veroeffentlichung>" >&2; exit 2; }
|
||||
|
||||
RELEASE_DIR="$ROOT/releases/$RELEASE"
|
||||
BACKEND="$RELEASE_DIR/backend"
|
||||
|
||||
step() { printf '\n\033[1m==> %s\033[0m\n' "$1"; }
|
||||
fail() { printf '\033[31mFEHLER: %s\033[0m\n' "$1" >&2; exit 1; }
|
||||
|
||||
# ── 1. Prüfen, was da hochgeladen wurde ──────────────────────────────────────
|
||||
step "Veröffentlichung $RELEASE prüfen"
|
||||
[ -d "$RELEASE_DIR" ] || fail "$RELEASE_DIR gibt es nicht."
|
||||
[ -f "$RELEASE_DIR/public/index.html" ] || fail "Im Bündel fehlt public/index.html."
|
||||
[ -f "$BACKEND/public/index.php" ] || fail "Im Backend fehlt public/index.php."
|
||||
[ -f "$ROOT/shared/.env" ] || fail "$ROOT/shared/.env fehlt. Einmalig aus backend/.env.example anlegen."
|
||||
|
||||
# ── 2. Gemeinsame Dateien einhängen ──────────────────────────────────────────
|
||||
# Die .env gehört dem Server, nicht dem Repository, und wird nie mit ausgerollt.
|
||||
step "Konfiguration verknüpfen"
|
||||
ln -sfn "$ROOT/shared/.env" "$BACKEND/.env"
|
||||
|
||||
# var/cache bleibt bewusst je Veröffentlichung eigen: dort liegt der von PHP-DI
|
||||
# kompilierte Container. Geteilt über mehrere Veröffentlichungen hinweg würde er
|
||||
# auf Klassen der alten Fassung zeigen.
|
||||
mkdir -p "$BACKEND/var/cache"
|
||||
chmod 2775 "$BACKEND/var" "$BACKEND/var/cache"
|
||||
|
||||
# ── 3. Abhängigkeiten auf der Zielmaschine auflösen ──────────────────────────
|
||||
# Bewusst hier und nicht im Gitea-Runner: nur hier stimmen PHP-Version und
|
||||
# Erweiterungen (pdo_pgsql, redis), sodass die Plattformprüfung von Composer
|
||||
# etwas Echtes prüft statt übersprungen zu werden.
|
||||
step "Composer-Abhängigkeiten installieren"
|
||||
( cd "$BACKEND" && composer install --no-dev --no-interaction --no-progress --prefer-dist --optimize-autoloader --classmap-authoritative )
|
||||
|
||||
# ── 4. Schema fortschreiben, bevor die neue Fassung sichtbar wird ────────────
|
||||
step "Datenbankschema fortschreiben"
|
||||
php "$BACKEND/bin/ekdos" migrate
|
||||
|
||||
# ── 5. Umschalten ────────────────────────────────────────────────────────────
|
||||
# ln -sfn legt bei einem vorhandenen Symlink sonst *im* Ziel an, deshalb erst
|
||||
# einen neuen Namen anlegen und dann mit mv -T atomar darüberschieben.
|
||||
step "Auf $RELEASE umschalten"
|
||||
PREVIOUS="$(readlink "$ROOT/current" 2>/dev/null || echo '')"
|
||||
ln -sfn "releases/$RELEASE" "$ROOT/current.new"
|
||||
mv -Tf "$ROOT/current.new" "$ROOT/current"
|
||||
[ -n "$PREVIOUS" ] && printf '%s\n' "$PREVIOUS" > "$ROOT/previous" || true
|
||||
|
||||
# ── 6. php-fpm neu laden ─────────────────────────────────────────────────────
|
||||
# Der Pool fährt mit opcache.validate_timestamps=0. Ohne Neuladen liefe weiter
|
||||
# der alte Quelltext aus dem Opcache.
|
||||
step "$FPM_SERVICE neu laden"
|
||||
sudo systemctl reload "$FPM_SERVICE"
|
||||
|
||||
# ── 7. Zwischenspeicher verwerfen ────────────────────────────────────────────
|
||||
# Zwischengespeicherte n8n-Antworten passen womöglich nicht mehr zur neuen
|
||||
# Feldabbildung. Sitzungen bleiben unberührt -- niemand wird abgemeldet.
|
||||
step "n8n-Cache verwerfen"
|
||||
php "$BACKEND/bin/ekdos" cache:flush
|
||||
|
||||
# ── 8. Nachsehen, ob es läuft ────────────────────────────────────────────────
|
||||
step "Gesundheitsprüfung"
|
||||
for attempt in 1 2 3 4 5; do
|
||||
if curl -fsS --max-time 5 "$HEALTH_URL" > /dev/null; then
|
||||
echo " $HEALTH_URL antwortet."
|
||||
break
|
||||
fi
|
||||
|
||||
[ "$attempt" -eq 5 ] && fail "$HEALTH_URL antwortet nicht. Zurück mit: $ROOT/deploy/rollback.sh"
|
||||
echo " Versuch $attempt fehlgeschlagen, neuer Versuch …"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# ── 9. Aufräumen ─────────────────────────────────────────────────────────────
|
||||
# Die aktuelle und die vorige Veröffentlichung bleiben in jedem Fall liegen.
|
||||
step "Alte Veröffentlichungen aufräumen (die letzten $KEEP bleiben)"
|
||||
KEEP_LIST="$(printf '%s\n%s\n' "$RELEASE" "$(basename "${PREVIOUS:-none}")")"
|
||||
|
||||
# find statt ls: kein unexpandiertes */-Glob, das unter `pipefail` den ganzen
|
||||
# Lauf nach einem bereits erfolgreichen Ausrollen scheitern liesse.
|
||||
OBSOLETE="$(cd "$ROOT/releases" && find . -mindepth 1 -maxdepth 1 -type d -printf '%T@ %f\n' \
|
||||
| sort -rn | cut -d' ' -f2- | tail -n "+$((KEEP + 1))" || true)"
|
||||
|
||||
if [ -n "$OBSOLETE" ]; then
|
||||
printf '%s\n' "$OBSOLETE" | while read -r old; do
|
||||
[ -n "$old" ] || continue
|
||||
|
||||
# Die aktive und die vorige Veröffentlichung bleiben in jedem Fall liegen.
|
||||
if printf '%s\n' "$KEEP_LIST" | grep -qxF "$old"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo " entferne $old"
|
||||
rm -rf -- "$ROOT/releases/$old"
|
||||
done
|
||||
else
|
||||
echo " nichts aufzuräumen"
|
||||
fi
|
||||
|
||||
step "$RELEASE ist aktiv."
|
||||
Reference in New Issue
Block a user