Files
nexus/.gitea/scripts/deploy-nexus.sh
T

199 lines
5.1 KiB
Bash
Executable File

#!/bin/sh
set -eu
DEPLOY_PATH="${DEPLOY_PATH:-/home/projekte_bao/nexus}"
ENV_TMPFILE_TEMPLATE="${ENV_TMPFILE:-/tmp/nexus-deploy-env}"
ENV_TMPFILE=""
BASE_URL="${BASE_URL:-https://nexus.noveria.net}"
cleanup() {
if [ -n "$ENV_TMPFILE" ] && [ -f "$ENV_TMPFILE" ]; then
shred -u "$ENV_TMPFILE" 2>/dev/null || rm -f "$ENV_TMPFILE"
fi
}
trap cleanup EXIT INT TERM
require_env() {
name="$1"
eval "value=\${$name:-}"
if [ -z "$value" ]; then
echo "Missing required environment variable: $name" >&2
exit 1
fi
}
require_env ENV_POSTGRES_PASSWORD
require_env ENV_JWT_KEY
secure_tmpfile() {
template="$1"
dir="$(dirname "$template")"
base="$(basename "$template")"
mkdir -p "$dir"
mktemp "$dir/$base.XXXXXX"
}
ENV_TMPFILE="$(secure_tmpfile "$ENV_TMPFILE_TEMPLATE")"
chmod 600 "$ENV_TMPFILE"
if [ ! -f VERSION ]; then
echo "VERSION file not found" >&2
exit 1
fi
VERSION="$(tr -d '[:space:]' < VERSION)"
if ! echo "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "Invalid VERSION value: $VERSION" >&2
exit 1
fi
GIT_SHA="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
GIT_REF="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
echo "Deploying Nexus v$VERSION from $GIT_REF"
umask 077
cat > "$ENV_TMPFILE" <<EOF_ENV
POSTGRES_DB=nexus
POSTGRES_USER=nexus
POSTGRES_PASSWORD=${ENV_POSTGRES_PASSWORD}
JWT_KEY=${ENV_JWT_KEY}
JWT_ISSUER=nexus
JWT_AUDIENCE=nexus-web
BOOTSTRAP_OWNER_EMAIL=vmbao62@hotmail.de
OPENCLAW_BASE_URL=http://openclaw-gateway-bao:18789
OPENCLAW_GATEWAY_TOKEN=${ENV_OPENCLAW_TOKEN:-}
OPENCLAW_GATEWAY_PASSWORD=
NEXUS_VERSION=${VERSION}
NEXUS_GIT_SHA=${GIT_SHA}
EOF_ENV
echo "Syncing source to deploy path: $DEPLOY_PATH"
git archive --format=tar HEAD | docker run --rm -i \
-v "$DEPLOY_PATH:/dest" \
alpine:3.20 \
sh -c '
set -eu
dest_owner="$(stat -c "%u:%g" /dest)"
mkdir -p /src-snapshot
tar -xf - -C /src-snapshot
is_protected_path() {
case "$1" in
./.git|./.git/*|./.env|./.env.*|./data|./data/*|./logs|./logs/*|./backups|./backups/*|./tmp|./tmp/*|./uploads|./uploads/*|./storage|./storage/*)
return 0
;;
*)
return 1
;;
esac
}
cd /dest
find . -mindepth 1 -maxdepth 1 | while IFS= read -r path; do
if ! is_protected_path "$path"; then
rm -rf "$path"
fi
done
cd /src-snapshot
find . -mindepth 1 -maxdepth 1 | while IFS= read -r path; do
if ! is_protected_path "$path"; then
cp -a "$path" /dest/
fi
done
chown -R "$dest_owner" /dest
'
echo "Building and starting Docker compose stack"
docker run --rm \
-v "$DEPLOY_PATH:/workspace/nexus" \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /workspace/nexus \
-i \
docker:cli \
sh -c 'set -eu
umask 077
cat > /tmp/nexus-deploy-env
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 up -d --force-recreate --remove-orphans --wait
docker compose --env-file /tmp/nexus-deploy-env ps
' < "$ENV_TMPFILE"
echo "Verifying image provenance"
for container in nexus-api-1 nexus-web-1; do
revision="$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.revision" }}' "$container")"
version="$(docker inspect --format '{{ index .Config.Labels "org.opencontainers.image.version" }}' "$container")"
if [ "$revision" != "$GIT_SHA" ]; then
echo "Image revision mismatch for $container: expected $GIT_SHA, got $revision" >&2
exit 1
fi
if [ "$version" != "$VERSION" ]; then
echo "Image version mismatch for $container: expected $VERSION, got $version" >&2
exit 1
fi
echo "$container provenance verified: v$version $revision"
done
echo "Checking live health"
retry=0
while [ "$retry" -lt 6 ]; do
retry=$((retry + 1))
health_body="$(curl -fsS --max-time 10 "$BASE_URL/health" 2>/dev/null || true)"
case "$health_body" in
'{"status":"Healthy"'*)
echo "Health check passed"
break
;;
esac
if [ -n "$health_body" ]; then
echo "Health endpoint is reachable but not healthy: $health_body" >&2
fi
if [ "$retry" -eq 6 ]; then
echo "Health check failed" >&2
exit 1
fi
sleep "$retry"
done
pass=0
fail=0
check() {
path="$1"
expected="$2"
label="$3"
code="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 "$BASE_URL$path")"
printf '%-28s HTTP %s\n' "$label" "$code"
if [ "$code" = "$expected" ]; then
pass=$((pass + 1))
else
fail=$((fail + 1))
fi
}
check_post() {
path="$1"
expected="$2"
label="$3"
code="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 10 -X POST -H 'Content-Type: application/json' --data '{}' "$BASE_URL$path")"
printf '%-28s HTTP %s\n' "$label" "$code"
if [ "$code" = "$expected" ]; then
pass=$((pass + 1))
else
fail=$((fail + 1))
fi
}
check "/dashboard" "200" "Dashboard"
check "/health" "200" "Health"
check "/api/v1/operations/snapshot" "401" "Operations auth"
check_post "/api/v1/chat" "401" "Chat auth"
if [ "$fail" -ne 0 ]; then
echo "Smoke test failed: $fail failed, $pass passed" >&2
exit 1
fi
echo "Nexus v$VERSION deployed and verified"