added zero downtime
This commit is contained in:
75
deploy_zero_downtime.sh
Executable file
75
deploy_zero_downtime.sh
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_DIR="/root/opt/bunkerserver/NewsSite"
|
||||||
|
BRANCH="main"
|
||||||
|
|
||||||
|
BLUE="server-app-blue"
|
||||||
|
GREEN="server-app-green"
|
||||||
|
|
||||||
|
HEALTH_PATH="/health" # falls du keinen hast: "/" nehmen
|
||||||
|
HEALTH_TIMEOUT=60
|
||||||
|
|
||||||
|
lock="/tmp/deploy_newssite.lock"
|
||||||
|
exec 9>"$lock"
|
||||||
|
flock -n 9 || { echo "Deploy läuft schon."; exit 1; }
|
||||||
|
|
||||||
|
log() { echo "[$(date -Is)] $*"; }
|
||||||
|
|
||||||
|
wait_healthy() {
|
||||||
|
local svc="$1"
|
||||||
|
local deadline=$(( $(date +%s) + HEALTH_TIMEOUT ))
|
||||||
|
log "Warte bis $svc healthy ist…"
|
||||||
|
|
||||||
|
while (( $(date +%s) < deadline )); do
|
||||||
|
local cid
|
||||||
|
cid="$(docker compose ps -q "$svc" || true)"
|
||||||
|
if [[ -n "$cid" ]]; then
|
||||||
|
# test via wget oder curl im container (eins von beiden sollte meistens da sein)
|
||||||
|
if docker exec "$cid" sh -lc "command -v curl >/dev/null && curl -fsS http://127.0.0.1:8080${HEALTH_PATH} >/dev/null" 2>/dev/null; then
|
||||||
|
log "$svc healthy ✅"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if docker exec "$cid" sh -lc "command -v wget >/dev/null && wget -qO- http://127.0.0.1:8080${HEALTH_PATH} >/dev/null" 2>/dev/null; then
|
||||||
|
log "$svc healthy ✅"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
log "Healthcheck failed für $svc ❌"
|
||||||
|
docker compose logs --tail=200 "$svc" || true
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
log "1) Git Pull (hart auf origin/$BRANCH)"
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
git fetch origin "$BRANCH"
|
||||||
|
git reset --hard "origin/$BRANCH"
|
||||||
|
|
||||||
|
SHA="$(git rev-parse --short HEAD)"
|
||||||
|
TAG="bunker-server-app:${SHA}"
|
||||||
|
log "2) Build Image: $TAG"
|
||||||
|
docker build -t "$TAG" ./server-app
|
||||||
|
|
||||||
|
# Green bekommt neues Tag (damit green garantiert neu ist)
|
||||||
|
docker tag "$TAG" bunker-server-app:green
|
||||||
|
# Blue bekommt später neues Tag
|
||||||
|
docker tag "$TAG" bunker-server-app:blue
|
||||||
|
|
||||||
|
log "3) GREEN starten (parallel, ohne Downtime)"
|
||||||
|
# Wichtig: Compose-Override nur fürs Image wäre am saubersten – hier nutzen wir Tags:
|
||||||
|
# => dafür muss in compose beim service-image statt latest die tags green/blue stehen (siehe Hinweis unten)
|
||||||
|
docker compose up -d --no-deps --force-recreate "$GREEN"
|
||||||
|
wait_healthy "$GREEN"
|
||||||
|
|
||||||
|
log "4) BLUE ersetzen (während GREEN ausliefert)"
|
||||||
|
docker compose up -d --no-deps --force-recreate "$BLUE"
|
||||||
|
wait_healthy "$BLUE"
|
||||||
|
|
||||||
|
log "5) GREEN stoppen & entfernen"
|
||||||
|
docker compose stop "$GREEN" || true
|
||||||
|
docker compose rm -f "$GREEN" || true
|
||||||
|
|
||||||
|
log "Deploy abgeschlossen ✅"
|
||||||
Reference in New Issue
Block a user