From 182b21f19235c9dffd0373e0ace65edefb7d97c6 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Thu, 3 Sep 2026 21:19:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=94=9F=E4=BA=A7=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=20npm=20=E6=9E=84=E5=BB=BA=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/caddy/Dockerfile | 5 +++- scripts/deploy-prod.sh | 56 +++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/deploy/caddy/Dockerfile b/deploy/caddy/Dockerfile index 02bd276..33334d9 100644 --- a/deploy/caddy/Dockerfile +++ b/deploy/caddy/Dockerfile @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.7 + # 第一阶段:构建主站前端静态资源 FROM node:24-alpine AS build @@ -6,7 +8,8 @@ ENV VITE_ADMIN_BASE_PATH=${VITE_ADMIN_BASE_PATH} WORKDIR /src COPY frontend/package*.json ./ -RUN npm ci +RUN --mount=type=cache,target=/root/.npm \ + npm ci --prefer-offline --no-audit --fund=false COPY frontend/ . RUN npm run build diff --git a/scripts/deploy-prod.sh b/scripts/deploy-prod.sh index cef2192..0b9388b 100755 --- a/scripts/deploy-prod.sh +++ b/scripts/deploy-prod.sh @@ -82,6 +82,10 @@ show_help() { 选号网源码目录(相对 hfb_sys 根目录或绝对路径) 构建优先用本机 npm;没有 npm 时自动用 Docker node 镜像,服务器不必装 Node +说明: + npm 仅用于构建前端静态资源,运行已构建的 Docker 镜像不需要 npm。 + 已完成一次完整部署后,日常启动可使用 --no-build。 + 示例: ./scripts/deploy-prod.sh ./scripts/deploy-prod.sh --no-build @@ -304,6 +308,17 @@ prepare_show_site() { return 0 fi + if [[ "${NO_BUILD}" == "1" ]]; then + # 运行已有镜像不需要 Node/npm;仅重新生成绑定挂载的 Caddy 站点配置。 + log_warn "--no-build:复用已有选号网静态资源,不执行 npm 构建" + if [[ "${show_domain}" == http://* || "${show_domain}" == https://* || "${show_domain}" == */* || "${show_domain}" == "${CADDY_DOMAIN}" || ! "${show_domain}" =~ ^[A-Za-z0-9.-]+$ ]]; then + log_error "CADDY_SHOW_DOMAIN 配置不正确:${show_domain}" + exit 1 + fi + sed "s/__CADDY_SHOW_DOMAIN__/${show_domain}/g" "${show_tmpl}" >"${show_conf}" + return 0 + fi + if [[ "${show_domain}" == http://* || "${show_domain}" == https://* || "${show_domain}" == */* ]]; then log_error "CADDY_SHOW_DOMAIN 只填写域名本身,不要包含 http(s):// 或路径,当前值:${show_domain}" exit 1 @@ -330,13 +345,7 @@ prepare_show_site() { exit 1 fi - if [[ "${NO_BUILD}" == "1" ]]; then - if [[ ! -f "${show_dist}/index.html" ]] || grep -q '选号网静态资源尚未构建' "${show_dist}/index.html" 2>/dev/null; then - log_error "--no-build 时需要已有 deploy/caddy/show-dist 构建产物,请先完整部署一次" - exit 1 - fi - log_warn "使用已有 show-dist(--no-build)" - else + if [[ "${NO_BUILD}" != "1" ]]; then # 服务器通常无本机 Node:优先本机 npm,否则用 Docker 内 node 镜像构建。 # 国内机访问 registry.npmjs.org 易 ECONNRESET,默认走 npmmirror,可用 NPM_REGISTRY 覆盖。 local npm_registry npm_install @@ -353,11 +362,17 @@ prepare_show_site() { if command -v npm >/dev/null 2>&1; then ( cd "${show_dir}" - ${npm_install} \ - --registry="${npm_registry}" \ - --fetch-retries=5 \ - --fetch-retry-mintimeout=20000 \ - --fetch-retry-maxtimeout=120000 + deps_hash="$( { sha256sum package.json; if [[ -f package-lock.json ]]; then sha256sum package-lock.json; fi; } | sha256sum | awk '{print $1}')" + if [[ ! -d node_modules || ! -f .hfb-deps-hash || "$(cat .hfb-deps-hash)" != "${deps_hash}" ]]; then + ${npm_install} \ + --registry="${npm_registry}" \ + --fetch-retries=5 \ + --fetch-retry-mintimeout=20000 \ + --fetch-retry-maxtimeout=120000 + printf '%s\n' "${deps_hash}" > .hfb-deps-hash + else + log "选号网依赖未变化,跳过 npm 安装" + fi npm run build ) else @@ -366,10 +381,25 @@ prepare_show_site() { # 挂载源码目录;node_modules/dist 写在挂载卷上,与本机 npm 行为一致 docker run --rm \ -e npm_config_registry="${npm_registry}" \ + -e HFB_NPM_INSTALL="${npm_install}" \ -v "${show_dir}:/app" \ -w /app \ node:24-alpine \ - sh -c "${npm_install} --registry=${npm_registry} --fetch-retries=5 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 && npm run build" + sh -c ' + set -eu + deps_hash="$( { sha256sum package.json; if [ -f package-lock.json ]; then sha256sum package-lock.json; fi; } | sha256sum | awk '\''{print $1}'\'')" + if [ ! -d node_modules ] || [ ! -f .hfb-deps-hash ] || [ "$(cat .hfb-deps-hash)" != "$deps_hash" ]; then + if [ "$HFB_NPM_INSTALL" = "npm ci" ]; then + npm ci --registry="$npm_config_registry" --fetch-retries=5 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 + else + npm install --registry="$npm_config_registry" --fetch-retries=5 --fetch-retry-mintimeout=20000 --fetch-retry-maxtimeout=120000 + fi + printf "%s\\n" "$deps_hash" > .hfb-deps-hash + else + echo "选号网依赖未变化,跳过 npm 安装" + fi + npm run build + ' fi if [[ ! -d "${show_dir}/dist" ]]; then log_error "选号网构建失败:未生成 dist/"