fix: 统一前端Harbor镜像发布与拉取部署

This commit is contained in:
Yvan
2026-11-05 13:08:56 +08:00
parent 5f6e893457
commit af2a2a44b3
13 changed files with 201 additions and 61 deletions
+48 -15
View File
@@ -2,18 +2,32 @@
set -Eeuo pipefail
umask 027
TAG="${1:?Usage: deploy.sh VERSION [--build-only]}"
MODE="${2:-}"
TAG="${1:?Usage: deploy.sh VERSION [--build-only] [--pull-only]}"
shift
BUILD_ONLY=false
PULL_ONLY=false
for mode in "$@"; do
case "$mode" in
'') ;;
--build-only) BUILD_ONLY=true ;;
--pull-only) PULL_ONLY=true ;;
*) echo 'Invalid deployment mode' >&2; exit 1 ;;
esac
done
[[ "$TAG" =~ ^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,79}$ ]] || { echo 'Invalid version' >&2; exit 1; }
[[ -z "$MODE" || "$MODE" == '--build-only' ]] || { echo 'Invalid deployment mode' >&2; exit 1; }
BASE_DIR="${SW_DEPLOY_BASE:-/www/wwwroot/sw2.fuhua91.com}"
BASE_DIR=$(cd -- "$BASE_DIR" && pwd -P)
RELEASE=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
[[ "$RELEASE" == "$BASE_DIR/frontend-releases/$TAG" ]] || { echo 'Release directory does not match version' >&2; exit 1; }
if [[ -s "$BASE_DIR/harbor-docker/config.json" ]]; then export DOCKER_CONFIG="$BASE_DIR/harbor-docker"; fi
RELEASE=''
if [[ "$PULL_ONLY" == false ]]; then
RELEASE=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
[[ "$RELEASE" == "$BASE_DIR/frontend-releases/$TAG" ]] || { echo 'Release directory does not match version' >&2; exit 1; }
fi
NAME=sw2-frontend
PREVIOUS=sw2-frontend-previous
CANDIDATE="sw2-frontend-candidate-$$"
IMAGE="sw2/frontend:$TAG"
IMAGE_REPOSITORY=harbor.fuhua91.com/game/sw2
IMAGE="$IMAGE_REPOSITORY:$TAG"
NETWORK=sw2-net
ATTEMPTS="${SW_HEALTH_ATTEMPTS:-20}"
[[ "$ATTEMPTS" =~ ^[1-9][0-9]?$ ]] || { echo 'Invalid health-check attempts' >&2; exit 1; }
@@ -34,8 +48,10 @@ if exists "$PREVIOUS"; then
fi
! exists "$CANDIDATE" || { echo 'Candidate container already exists' >&2; exit 1; }
docker network inspect "$NETWORK" >/dev/null
test -s "$RELEASE/dist/index.html"
[[ "$(cat "$RELEASE/dist/version.txt")" == "$TAG" ]] || { echo 'Frontend version marker mismatch' >&2; exit 1; }
if [[ "$PULL_ONLY" == false ]]; then
test -s "$RELEASE/dist/index.html"
[[ "$(cat "$RELEASE/dist/version.txt")" == "$TAG" ]] || { echo 'Frontend version marker mismatch' >&2; exit 1; }
fi
old_present=false
old_stopped=false
@@ -81,15 +97,32 @@ healthy() {
return 1
}
docker build --build-arg "VERSION=$TAG" -t "$IMAGE" "$RELEASE"
docker run --rm "$IMAGE" nginx -t
if [[ "$PULL_ONLY" == false ]]; then
docker build --build-arg "VERSION=$TAG" -t "$IMAGE" "$RELEASE"
docker push "$IMAGE"
fi
# Resolve the registry result and pin every run to its digest. Authentication
# uses the server's docker login; credentials never enter the release package.
docker pull "$IMAGE"
digests=$(docker inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$IMAGE")
IMAGE_REF=''
while IFS= read -r reference; do
if [[ "$reference" == "$IMAGE_REPOSITORY@sha256:"* && "${reference##*@}" =~ ^sha256:[a-f0-9]{64}$ ]]; then
IMAGE_REF="$reference"
break
fi
done <<< "$digests"
[[ -n "$IMAGE_REF" ]] || { echo 'Harbor image digest is missing' >&2; exit 1; }
mkdir -p "$BASE_DIR/frontend-images"
printf '%s\n' "$IMAGE_REF" > "$BASE_DIR/frontend-images/$TAG.ref"
docker run --rm "$IMAGE_REF" nginx -t
docker run -d --name "$CANDIDATE" --label com.sw2.application=sw2 --label com.sw2.component=frontend \
--network "$NETWORK" -p 127.0.0.1::80 "$IMAGE" >/dev/null
--network "$NETWORK" -p 127.0.0.1::80 "$IMAGE_REF" >/dev/null
candidate_address=$(docker port "$CANDIDATE" 80/tcp)
[[ "$candidate_address" =~ ^127\.0\.0\.1:[0-9]+$ ]] || { echo 'Unexpected candidate binding' >&2; exit 1; }
healthy "http://$candidate_address" || { echo 'Candidate frontend or API proxy failed preflight' >&2; exit 1; }
if [[ "$MODE" == '--build-only' ]]; then
echo "Frontend image and API proxy preflight passed: $TAG"
if [[ "$BUILD_ONLY" == true ]]; then
echo "Harbor frontend image and API proxy preflight passed: $IMAGE_REF"
exit 0
fi
@@ -104,7 +137,7 @@ created=true
docker run -d --name "$NAME" --label com.sw2.application=sw2 --label com.sw2.component=frontend \
--restart unless-stopped --network "$NETWORK" \
--log-opt max-size=20m --log-opt max-file=3 \
-p 127.0.0.1:9601:80 "$IMAGE" >/dev/null
-p 127.0.0.1:9601:80 "$IMAGE_REF" >/dev/null
healthy http://127.0.0.1:9601 || { echo 'Published frontend failed health checks' >&2; exit 1; }
if [[ -n "$old_version" ]]; then
@@ -114,4 +147,4 @@ fi
printf '%s\n' "$TAG" > "$BASE_DIR/current-frontend-release.tmp"
mv -f -- "$BASE_DIR/current-frontend-release.tmp" "$BASE_DIR/current-frontend-release"
committed=true
printf 'Frontend deployed: %s\nBackend container was not modified.\n' "$TAG"
printf 'Frontend deployed: %s\nImage: %s\nBackend container was not modified.\n' "$TAG" "$IMAGE_REF"