diff --git a/compose-Nas.yml b/compose-Nas.yml index c288cf7..58233fb 100644 --- a/compose-Nas.yml +++ b/compose-Nas.yml @@ -31,7 +31,7 @@ services: retries: 10 reactive_resume_app: - image: amruthpillai/reactive-resume:latest + image: amruthpillai/reactive-resume@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa restart: unless-stopped depends_on: reactive_resume_permissions: @@ -97,7 +97,7 @@ services: # QTS/Container Station 版默认启动 frpc。 # 为避免 QTS 把 frpc 配置文件挂载路径改到应用临时目录,这里不挂载 frpc.yaml, # 而是在容器启动时自动写入 /tmp/frpc.toml。 - image: snowdreamtech/frpc:latest + image: fatedier/frpc:v0.68.0 restart: unless-stopped entrypoint: ["/bin/sh"] command: diff --git a/compose.yml b/compose.yml index d115490..0d58041 100644 --- a/compose.yml +++ b/compose.yml @@ -19,7 +19,7 @@ services: retries: 10 reactive-resume: - image: amruthpillai/reactive-resume:latest + image: amruthpillai/reactive-resume@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa restart: unless-stopped env_file: - .env diff --git a/dist/SHA256SUMS b/dist/SHA256SUMS index 227f15b..5a2b15c 100644 --- a/dist/SHA256SUMS +++ b/dist/SHA256SUMS @@ -1,3 +1,3 @@ -fa3b2b64a9afd7af60f57cfda8431af4e171cc1cdba4a6a2b89d50000a574f54 reactive-resume-clean-install-20260520.zip -6724400586b14de9a954dcb22e1b7150d8339b3ebf07bb5b0685a5aa60009bc9 reactive-resume-personal-direct-20260520.zip -21e588dc25e90e358f823175cfab7ef4b4880fed959bab8d9d7c65200848b6d0 reactive-resume-personal-qnap-nas-20260520.zip +62d2a619dbade4a2fad0a9fbf4ff3389fed7afd9b5556b5d1e0a414d69ccd9dd reactive-resume-clean-install-20260520.zip +b737f2e75437c25e32760ca81532c27bfc0f5455e12afca14a3439af8b2851c1 reactive-resume-personal-direct-20260520.zip +c3414564cadd093e93b2bf9769bbb9eafc8e760cf98a216340516db2aea3007f reactive-resume-personal-qnap-nas-20260520.zip diff --git a/dist/SHA256SUMS-20260520 b/dist/SHA256SUMS-20260520 index 227f15b..5a2b15c 100644 --- a/dist/SHA256SUMS-20260520 +++ b/dist/SHA256SUMS-20260520 @@ -1,3 +1,3 @@ -fa3b2b64a9afd7af60f57cfda8431af4e171cc1cdba4a6a2b89d50000a574f54 reactive-resume-clean-install-20260520.zip -6724400586b14de9a954dcb22e1b7150d8339b3ebf07bb5b0685a5aa60009bc9 reactive-resume-personal-direct-20260520.zip -21e588dc25e90e358f823175cfab7ef4b4880fed959bab8d9d7c65200848b6d0 reactive-resume-personal-qnap-nas-20260520.zip +62d2a619dbade4a2fad0a9fbf4ff3389fed7afd9b5556b5d1e0a414d69ccd9dd reactive-resume-clean-install-20260520.zip +b737f2e75437c25e32760ca81532c27bfc0f5455e12afca14a3439af8b2851c1 reactive-resume-personal-direct-20260520.zip +c3414564cadd093e93b2bf9769bbb9eafc8e760cf98a216340516db2aea3007f reactive-resume-personal-qnap-nas-20260520.zip diff --git a/dist/reactive-resume-clean-install-20260520.zip b/dist/reactive-resume-clean-install-20260520.zip index 34d4055..82011ae 100644 Binary files a/dist/reactive-resume-clean-install-20260520.zip and b/dist/reactive-resume-clean-install-20260520.zip differ diff --git a/dist/reactive-resume-personal-direct-20260520.zip b/dist/reactive-resume-personal-direct-20260520.zip index 3ac46c5..039160d 100644 Binary files a/dist/reactive-resume-personal-direct-20260520.zip and b/dist/reactive-resume-personal-direct-20260520.zip differ diff --git a/dist/reactive-resume-personal-qnap-nas-20260520.zip b/dist/reactive-resume-personal-qnap-nas-20260520.zip index bdea257..d7cd316 100644 Binary files a/dist/reactive-resume-personal-qnap-nas-20260520.zip and b/dist/reactive-resume-personal-qnap-nas-20260520.zip differ diff --git a/packages/reactive-resume-clean-install/compose-Nas.yml b/packages/reactive-resume-clean-install/compose-Nas.yml index df51d02..d1f9832 100644 --- a/packages/reactive-resume-clean-install/compose-Nas.yml +++ b/packages/reactive-resume-clean-install/compose-Nas.yml @@ -34,7 +34,7 @@ services: retries: 10 reactive_resume_app: - image: amruthpillai/reactive-resume:latest + image: amruthpillai/reactive-resume@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa restart: unless-stopped depends_on: reactive_resume_permissions: @@ -68,7 +68,7 @@ services: start_period: 30s reactive_resume_frpc: - image: snowdreamtech/frpc:latest + image: fatedier/frpc:v0.68.0 restart: unless-stopped entrypoint: ["/bin/sh"] command: diff --git a/packages/reactive-resume-clean-install/compose.yml b/packages/reactive-resume-clean-install/compose.yml index f0025df..47a8aaf 100644 --- a/packages/reactive-resume-clean-install/compose.yml +++ b/packages/reactive-resume-clean-install/compose.yml @@ -22,7 +22,7 @@ services: retries: 10 reactive-resume: - image: amruthpillai/reactive-resume:latest + image: amruthpillai/reactive-resume@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa restart: unless-stopped env_file: - .env diff --git a/packages/reactive-resume-personal-direct/compose.yml b/packages/reactive-resume-personal-direct/compose.yml index bd7cfec..960f66c 100644 --- a/packages/reactive-resume-personal-direct/compose.yml +++ b/packages/reactive-resume-personal-direct/compose.yml @@ -19,7 +19,7 @@ services: retries: 10 reactive-resume: - image: amruthpillai/reactive-resume:latest + image: amruthpillai/reactive-resume@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa restart: unless-stopped entrypoint: ["/bin/sh", "/opt/reactive-resume-patches/reactive-resume-entrypoint.sh"] env_file: diff --git a/packages/reactive-resume-personal-qnap-nas/compose-Nas.yml b/packages/reactive-resume-personal-qnap-nas/compose-Nas.yml index 8c8078f..c58ba99 100644 --- a/packages/reactive-resume-personal-qnap-nas/compose-Nas.yml +++ b/packages/reactive-resume-personal-qnap-nas/compose-Nas.yml @@ -42,7 +42,7 @@ services: retries: 10 reactive_resume_app: - image: amruthpillai/reactive-resume:latest + image: amruthpillai/reactive-resume@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa restart: unless-stopped entrypoint: ["/bin/sh", "/opt/reactive-resume-patches/reactive-resume-entrypoint.sh"] depends_on: @@ -144,7 +144,7 @@ services: condition: service_healthy reactive_resume_frpc: - image: snowdreamtech/frpc:latest + image: fatedier/frpc:v0.68.0 restart: unless-stopped environment: HTTP_PROXY: http://192.168.3.12:7893 diff --git a/scripts/test-personal-install-packages.sh b/scripts/test-personal-install-packages.sh index e755af7..b144504 100755 --- a/scripts/test-personal-install-packages.sh +++ b/scripts/test-personal-install-packages.sh @@ -9,7 +9,8 @@ QNAP_PATCH_DIR="$ROOT_DIR/packages/reactive-resume-personal-qnap-nas/patches" DIRECT_PATCH_DIR="$ROOT_DIR/packages/reactive-resume-personal-direct/patches" QNAP_ZIP="$ROOT_DIR/dist/reactive-resume-personal-qnap-nas-20260520.zip" DIRECT_ZIP="$ROOT_DIR/dist/reactive-resume-personal-direct-20260520.zip" -IMAGE="amruthpillai/reactive-resume:latest" +IMAGE_REPO="amruthpillai/reactive-resume" +IMAGE_INDEX="$IMAGE_REPO@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa" PROJECT="reactive-resume-personal" log() { @@ -64,6 +65,12 @@ unzip -l "$DIRECT_ZIP" | grep -q 'reactive-resume-personal-direct/patches/reacti if unzip -p "$QNAP_ZIP" 'reactive_resume/*' 2>/dev/null | grep -E 'isiseg|10004|Reactive_Resume_Personal|/share/Container/Reactive_Resume_Personal' >/dev/null; then fail "QNAP zip 中仍有旧域名、旧端口或旧路径" fi +if unzip -p "$QNAP_ZIP" 'reactive_resume/*' 2>/dev/null | grep -E 'amruthpillai/reactive-resume:latest|snowdreamtech/frpc:latest' >/dev/null; then + fail "QNAP zip 中仍有 latest 镜像" +fi +if unzip -p "$DIRECT_ZIP" 'reactive-resume-personal-direct/*' 2>/dev/null | grep -E 'amruthpillai/reactive-resume:latest|snowdreamtech/frpc:latest' >/dev/null; then + fail "direct zip 中仍有 latest 镜像" +fi log "真实启动 direct 包并检查健康状态" cleanup_direct @@ -102,7 +109,7 @@ fi log "离线检查 arm64/QNAP 镜像布局" ARM64_DIGEST="$( - docker manifest inspect "$IMAGE" \ + docker manifest inspect "$IMAGE_INDEX" \ | node -e ' let source = ""; process.stdin.on("data", (chunk) => source += chunk); @@ -116,15 +123,31 @@ process.stdin.on("end", () => { )" TMP_DIR="$(mktemp -d)" -CID="$(docker create --platform linux/arm64 "$IMAGE@$ARM64_DIGEST" 2>/dev/null || true)" +CID="$(docker create --platform linux/arm64 "$IMAGE_INDEX" 2>/dev/null || true)" [ -n "$CID" ] || fail "无法创建 arm64 镜像容器用于离线检查" docker export "$CID" -o "$TMP_DIR/arm64-root.tar" docker rm "$CID" >/dev/null mkdir -p "$TMP_DIR/arm64-root" tar -xf "$TMP_DIR/arm64-root.tar" -C "$TMP_DIR/arm64-root" -[ -f "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" ] || fail "arm64 镜像中未找到 /app/apps/server/dist/index.mjs" -[ -d "$TMP_DIR/arm64-root/app/apps/web/dist/assets" ] || fail "arm64 镜像中未找到 /app/apps/web/dist/assets" +if [ -f "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" ]; then + ARM64_SERVER_ENTRY="$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" + ARM64_FILENAME_ENTRY="$ARM64_SERVER_ENTRY" + ARM64_ASSETS_DIR="$TMP_DIR/arm64-root/app/apps/web/dist/assets" + EXPECTED_ENTRYPOINT_PWD="$TMP_DIR/arm64-root/app" + EXPECTED_ENTRYPOINT_ARGS="node apps/server/dist/index.mjs" +elif [ -f "$TMP_DIR/arm64-root/app/apps/web/.output/server/index.mjs" ]; then + ARM64_SERVER_ENTRY="$TMP_DIR/arm64-root/app/apps/web/.output/server/index.mjs" + ARM64_FILENAME_ENTRY="$(grep -Rsl 'function generateFilename' "$TMP_DIR/arm64-root/app/apps/web/.output/server/_ssr" 2>/dev/null | head -n 1 || true)" + [ -n "$ARM64_FILENAME_ENTRY" ] || fail "arm64 .output 布局中未找到 generateFilename SSR bundle" + ARM64_ASSETS_DIR="$TMP_DIR/arm64-root/app/apps/web/.output/public/assets" + EXPECTED_ENTRYPOINT_PWD="$TMP_DIR/arm64-root/app/apps/web" + EXPECTED_ENTRYPOINT_ARGS="node .output/server/index.mjs" +else + find "$TMP_DIR/arm64-root/app" -maxdepth 6 \( -name index.mjs -o -name server.js -o -name main.js \) 2>/dev/null >&2 || true + fail "arm64 镜像中未找到支持的服务入口" +fi +[ -d "$ARM64_ASSETS_DIR" ] || fail "arm64 镜像中未找到 assets 目录:$ARM64_ASSETS_DIR" perl -0pe " s#/app/apps#$TMP_DIR/arm64-root/app/apps#g; @@ -138,13 +161,13 @@ sh "$TMP_DIR/runtime-patch-arm64-test.sh" >/tmp/reactive-resume-arm64-runtime.lo fail "arm64 离线运行 runtime patch 失败" } -grep -R 'rr-browser-buffer-polyfill' "$TMP_DIR/arm64-root/app/apps/web/dist/assets" >/dev/null \ +grep -R 'rr-browser-buffer-polyfill' "$ARM64_ASSETS_DIR" >/dev/null \ || fail "arm64 public PDF bundle 未注入 Buffer polyfill" -grep -R -F 'replace(/[\\/:*?"<>|]/g' "$TMP_DIR/arm64-root/app/apps/web/dist/assets" >/dev/null \ +grep -R -F 'replace(/[\\/:*?"<>|]/g' "$ARM64_ASSETS_DIR" >/dev/null \ || fail "arm64 文件名 bundle 未改为按标题下载" -grep -q 'function generateFilename(prefix, extension)' "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" \ +grep -q 'function generateFilename(prefix, extension)' "$ARM64_FILENAME_ENTRY" \ || fail "arm64 server entry 未包含 generateFilename" -grep -F 'filename.replace(/[\\/:*?"<>|]/g' "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" >/dev/null \ +grep -F 'filename.replace(/[\\/:*?"<>|]/g' "$ARM64_FILENAME_ENTRY" >/dev/null \ || fail "arm64 server entry 未改为按标题生成下载文件名" perl -0pe " @@ -165,10 +188,10 @@ PATH="$TMP_DIR/fakebin:$PATH" sh "$TMP_DIR/entrypoint-arm64-test.sh" >/tmp/react fail "arm64 entrypoint 选择测试失败" } -grep -q "PWD=$TMP_DIR/arm64-root/app" "$TMP_DIR/entrypoint-result.txt" \ - || fail "arm64 entrypoint 未切换到 /app" -grep -q "ARGS=node apps/server/dist/index.mjs" "$TMP_DIR/entrypoint-result.txt" \ - || fail "arm64 entrypoint 未选择 apps/server/dist/index.mjs" +grep -q "PWD=$EXPECTED_ENTRYPOINT_PWD" "$TMP_DIR/entrypoint-result.txt" \ + || fail "arm64 entrypoint 未切换到预期目录:$EXPECTED_ENTRYPOINT_PWD" +grep -q "ARGS=$EXPECTED_ENTRYPOINT_ARGS" "$TMP_DIR/entrypoint-result.txt" \ + || fail "arm64 entrypoint 未选择预期入口:$EXPECTED_ENTRYPOINT_ARGS" log "清理 direct 测试容器" cleanup_direct