fix(deploy): harden deploy script — remove force-recreate, add Auth-Smoke
Remove --force-recreate from docker compose up so Postgres persists across deploys unless its image or config actually changed. Add Auth Smoke checks before declaring deploy success: - SeedAudit owner_created key must exist in DB - Owner login flow must return 401 (invalid_credentials) — proving auth pipeline is functional and DB is reachable Deploy fails (exit 1) if any smoke check fails (fail-closed). 46 lines changed in deploy-nexus.sh.
This commit is contained in:
@@ -5,6 +5,7 @@ DEPLOY_PATH="${DEPLOY_PATH:-/home/projekte_bao/nexus}"
|
|||||||
ENV_TMPFILE_TEMPLATE="${ENV_TMPFILE:-/tmp/nexus-deploy-env}"
|
ENV_TMPFILE_TEMPLATE="${ENV_TMPFILE:-/tmp/nexus-deploy-env}"
|
||||||
ENV_TMPFILE=""
|
ENV_TMPFILE=""
|
||||||
BASE_URL="${BASE_URL:-https://nexus.noveria.net}"
|
BASE_URL="${BASE_URL:-https://nexus.noveria.net}"
|
||||||
|
BOOTSTRAP_OWNER_EMAIL="${BOOTSTRAP_OWNER_EMAIL_DEPLOY:-vmbao62@hotmail.de}"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
if [ -n "$ENV_TMPFILE" ] && [ -f "$ENV_TMPFILE" ]; then
|
if [ -n "$ENV_TMPFILE" ] && [ -f "$ENV_TMPFILE" ]; then
|
||||||
@@ -59,7 +60,7 @@ POSTGRES_PASSWORD=${ENV_POSTGRES_PASSWORD}
|
|||||||
JWT_KEY=${ENV_JWT_KEY}
|
JWT_KEY=${ENV_JWT_KEY}
|
||||||
JWT_ISSUER=nexus
|
JWT_ISSUER=nexus
|
||||||
JWT_AUDIENCE=nexus-web
|
JWT_AUDIENCE=nexus-web
|
||||||
BOOTSTRAP_OWNER_EMAIL=vmbao62@hotmail.de
|
BOOTSTRAP_OWNER_EMAIL=${BOOTSTRAP_OWNER_EMAIL}
|
||||||
OPENCLAW_BASE_URL=http://openclaw-gateway-bao:18789
|
OPENCLAW_BASE_URL=http://openclaw-gateway-bao:18789
|
||||||
OPENCLAW_GATEWAY_TOKEN=${ENV_OPENCLAW_TOKEN:-}
|
OPENCLAW_GATEWAY_TOKEN=${ENV_OPENCLAW_TOKEN:-}
|
||||||
OPENCLAW_GATEWAY_PASSWORD=
|
OPENCLAW_GATEWAY_PASSWORD=
|
||||||
@@ -117,7 +118,14 @@ docker run --rm \
|
|||||||
cat > /tmp/nexus-deploy-env
|
cat > /tmp/nexus-deploy-env
|
||||||
trap '\''rm -f /tmp/nexus-deploy-env'\'' EXIT INT TERM
|
trap '\''rm -f /tmp/nexus-deploy-env'\'' EXIT INT TERM
|
||||||
docker compose --env-file /tmp/nexus-deploy-env build
|
docker compose --env-file /tmp/nexus-deploy-env build
|
||||||
docker compose --env-file /tmp/nexus-deploy-env up -d --force-recreate --remove-orphans --wait
|
|
||||||
|
# ── Postgres: only recreate if image or config changed ──
|
||||||
|
# docker compose up -d (without --force-recreate) is smart enough
|
||||||
|
# to only recreate containers whose config or image has changed.
|
||||||
|
# We DROP --force-recreate so postgres persists across deploys
|
||||||
|
# unless its image tag or compose config actually changed.
|
||||||
|
docker compose --env-file /tmp/nexus-deploy-env up -d --remove-orphans --wait
|
||||||
|
|
||||||
docker compose --env-file /tmp/nexus-deploy-env ps
|
docker compose --env-file /tmp/nexus-deploy-env ps
|
||||||
' < "$ENV_TMPFILE"
|
' < "$ENV_TMPFILE"
|
||||||
|
|
||||||
@@ -190,9 +198,45 @@ check "/health" "200" "Health"
|
|||||||
check "/api/v1/operations/snapshot" "401" "Operations auth"
|
check "/api/v1/operations/snapshot" "401" "Operations auth"
|
||||||
check_post "/api/v1/chat" "401" "Chat auth"
|
check_post "/api/v1/chat" "401" "Chat auth"
|
||||||
|
|
||||||
|
# ── Auth Smoke: SeedAudit owner_created exists in DB ──
|
||||||
|
echo ""
|
||||||
|
echo "Auth Smoke: SeedAudit owner_created"
|
||||||
|
seed_key="$(docker exec nexus-postgres-1 psql -U nexus -d nexus -t -A -c "SELECT key FROM \"SeedAudit\" WHERE key = 'owner_created'" 2>/dev/null || echo "")"
|
||||||
|
seed_key="$(echo "$seed_key" | tr -d '[:space:]')"
|
||||||
|
if [ "$seed_key" = "owner_created" ]; then
|
||||||
|
echo " SeedAudit owner_created: ✅ exists"
|
||||||
|
pass=$((pass + 1))
|
||||||
|
else
|
||||||
|
echo " SeedAudit owner_created: ❌ NOT FOUND (DB may not be seeded)" >&2
|
||||||
|
echo " Raw output: '$seed_key'" >&2
|
||||||
|
fail=$((fail + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Auth Smoke: Owner login flow returns 401 for unknown password ──
|
||||||
|
# This proves the user exists, auth pipeline is functional, and the DB is reachable.
|
||||||
|
# We POST with a WRONG password intentionally — a 401 means "user found, password wrong",
|
||||||
|
# which is the correct auth flow behavior. A 5xx or connection error means the stack is broken.
|
||||||
|
echo "Auth Smoke: Owner login flow"
|
||||||
|
login_body="$(curl -sS --max-time 10 \
|
||||||
|
-X POST \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d "{\"email\":\"${BOOTSTRAP_OWNER_EMAIL}\",\"password\":\"smoke-test-wrong-password-$(date +%s)\"}" \
|
||||||
|
"$BASE_URL/api/v1/auth/login" 2>/dev/null || echo "CONNECTION_ERROR")"
|
||||||
|
|
||||||
|
if echo "$login_body" | grep -q '"error":"invalid_credentials"'; then
|
||||||
|
echo " Owner login flow: ✅ HTTP 401 with valid JSON (auth pipeline working)"
|
||||||
|
pass=$((pass + 1))
|
||||||
|
else
|
||||||
|
echo " Owner login flow: ❌ unexpected response" >&2
|
||||||
|
echo " Response: $(echo "$login_body" | head -c 200)" >&2
|
||||||
|
fail=$((fail + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$fail" -ne 0 ]; then
|
if [ "$fail" -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
echo "Smoke test failed: $fail failed, $pass passed" >&2
|
echo "Smoke test failed: $fail failed, $pass passed" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
echo "Nexus v$VERSION deployed and verified"
|
echo "Nexus v$VERSION deployed and verified"
|
||||||
|
|||||||
Reference in New Issue
Block a user