Harden pre-production deployment with external environment and preflights
This commit is contained in:
+61
-18
@@ -1,7 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
set +x
|
||||
set -Eeuo pipefail
|
||||
umask 077
|
||||
|
||||
trap 'status=$?; printf "FEHLER: Deployment in Zeile %s abgebrochen (Exit %s).\n" "$LINENO" "$status" >&2' ERR
|
||||
# The only active Pre-Production env source. Never source the checkout's .env.
|
||||
ENV_FILE='/home/kai/.config/metalcircle/preprod.env'
|
||||
DEPLOYMENT_STARTED=0
|
||||
on_error() {
|
||||
local status=$?
|
||||
if [[ "$DEPLOYMENT_STARTED" == 0 ]]; then
|
||||
printf 'Deployment aborted. Running container unchanged.\n' >&2
|
||||
else
|
||||
printf 'Deployment verification failed after the container update. Manual investigation required.\n' >&2
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
trap on_error ERR
|
||||
|
||||
CHECK_ONLY=0
|
||||
if [[ "${1:-}" == '--check' && "$#" == 1 ]]; then
|
||||
CHECK_ONLY=1
|
||||
elif [[ "$#" != 0 ]]; then
|
||||
printf 'Usage: ./scripts/deploy-preprod.sh [--check]\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd -P)"
|
||||
@@ -18,48 +40,69 @@ if [[ "$BRANCH" != "main" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$(git status --porcelain --untracked-files=all)" ]]; then
|
||||
WORKTREE_STATUS="$(git status --porcelain --untracked-files=all)"
|
||||
if [[ -n "$WORKTREE_STATUS" ]]; then
|
||||
printf 'FEHLER: Working Tree ist nicht sauber. Änderungen zuerst committen oder entfernen.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf 'Aktualisiere main mit Fast-Forward ...\n'
|
||||
git pull --ff-only origin main
|
||||
if [[ "$CHECK_ONLY" == 0 ]]; then
|
||||
printf 'Aktualisiere main mit Fast-Forward ...\n'
|
||||
git pull --ff-only origin main
|
||||
fi
|
||||
|
||||
host_check() {
|
||||
python3 "$SCRIPT_DIR/preprod_config.py" --env-file "$ENV_FILE" "$@"
|
||||
}
|
||||
|
||||
compose() {
|
||||
sudo docker compose -f compose.yml -f compose.preprod.yml "$@"
|
||||
# Executes sudo docker compose --env-file "$ENV_FILE" -f compose.yml -f compose.preprod.yml.
|
||||
# The helper clears ambient overrides and suppresses secret-bearing raw diagnostics.
|
||||
host_check compose "$@"
|
||||
}
|
||||
|
||||
run_preflight() {
|
||||
local output
|
||||
output="$("$@" python push_preflight.py \
|
||||
--expected-service-account metalcircle-push-preprod@metalcircle-30d9b.iam.gserviceaccount.com)"
|
||||
printf '%s\n' "$output"
|
||||
if [[ "$output" != PASS:* ]]; then
|
||||
printf 'FEHLER: Push-Preflight hat kein PASS geliefert.\n' >&2
|
||||
return 1
|
||||
fi
|
||||
"$@" python push_preflight.py \
|
||||
--expected-service-account metalcircle-push-preprod@metalcircle-30d9b.iam.gserviceaccount.com
|
||||
"$@" python gitea_preflight.py
|
||||
}
|
||||
|
||||
printf 'Prüfe externe Environment-Datei und Host-Secret ...\n'
|
||||
host_check check
|
||||
CONFIG_FINGERPRINT="$(host_check fingerprint)"
|
||||
printf 'Prüfe Pre-Production-Compose-Konfiguration ...\n'
|
||||
compose config --quiet
|
||||
|
||||
printf 'Baue Web-Image ...\n'
|
||||
compose build web
|
||||
|
||||
printf 'Prüfe Firebase-Credential im temporären Container ...\n'
|
||||
run_preflight compose run --rm --no-deps web
|
||||
printf 'Prüfe Firebase und Gitea im temporären Container ...\n'
|
||||
run_preflight compose run --rm --no-deps -T web
|
||||
|
||||
if [[ "$(host_check fingerprint)" != "$CONFIG_FINGERPRINT" ]]; then
|
||||
printf 'ERROR: Environment or Firebase secret changed during deployment. Start again.\n' >&2
|
||||
false
|
||||
fi
|
||||
|
||||
if [[ "$CHECK_ONLY" == 1 ]]; then
|
||||
printf 'PASS: Pre-Production preflights completed; running container unchanged.\n'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf 'Sichere geprüfte Environment-Datei außerhalb des Checkouts ...\n'
|
||||
host_check backup
|
||||
|
||||
printf 'Aktualisiere ausschließlich den Webcontainer ...\n'
|
||||
DEPLOYMENT_STARTED=1
|
||||
compose up -d --no-deps web
|
||||
|
||||
printf 'Prüfe Firebase-Credential im laufenden Webcontainer ...\n'
|
||||
printf 'Prüfe Firebase und Gitea im laufenden Webcontainer ...\n'
|
||||
run_preflight compose exec -T web
|
||||
|
||||
printf '\nCompose-Status:\n'
|
||||
compose ps
|
||||
compose ps --format json
|
||||
|
||||
printf '\nWeb-Logs der letzten 2 Minuten (maximal 100 Zeilen):\n'
|
||||
printf '\nWeb-Logs der letzten 2 Minuten (maximal 100 Zeilen, sicher gefiltert):\n'
|
||||
compose logs --since=2m --tail=100 --no-color web
|
||||
|
||||
printf '\nDeployter Git-Commit:\n'
|
||||
|
||||
Reference in New Issue
Block a user