diff --git a/Dockerfile.prod b/Dockerfile.prod index 3fa4337..f53534d 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,3 +1,14 @@ +# ---------- sharp 平台依赖构建阶段 ---------- +# 本地构建产物仅包含 darwin 平台二进制(@img/sharp-darwin-arm64), +# 容器运行于 Alpine(linuxmusl-x64),需补充 musl 平台二进制,否则媒体库接口报 500。 +FROM node:20-alpine AS sharp-deps +WORKDIR /sharp +# 使用空 package.json,仅安装两个 musl 平台包,避免安装完整依赖树撑爆磁盘 +RUN npm init -y >/dev/null 2>&1 && \ + npm install --no-save --os=linux --cpu=x64 --libc=musl \ + @img/sharp-linuxmusl-x64@0.35.3 \ + @img/sharp-libvips-linuxmusl-x64@1.3.2 + FROM node:20-alpine AS runner WORKDIR /app @@ -15,6 +26,8 @@ COPY dist/standalone ./ COPY dist/static ./dist/static # 公共静态资源(图片、字体、favicon、uploads 等) COPY public ./public +# 覆盖 sharp 平台依赖为 musl 版本(standalone 仅含 darwin 二进制) +COPY --from=sharp-deps /sharp/node_modules/@img /app/node_modules/@img RUN chown -R nextjs:nodejs /app diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 89304a5..b2a971b 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -130,6 +130,24 @@ cmd_build() { log "📋 构建静态站点" log "==========================================" cd "$PROJECT_ROOT" + + # 生产构建必须注入 .env.production 中的前后端加密密钥。 + # Next.js 加载 env 的优先级为 .env.local > .env.production, + # 若不显式注入,构建时会使用 .env.local 中的开发密钥, + # 导致前端 chunk 密钥与后端 ENCRYPTION_SECRET 不匹配, + # CMS 所有列表/仪表盘解密失败(The operation failed for an operation-specific reason)。 + if [[ -f "$PROJECT_ROOT/.env.production" ]]; then + PROD_ENC_SECRET=$(grep '^NEXT_PUBLIC_ENCRYPTION_SECRET=' "$PROJECT_ROOT/.env.production" | head -1 | cut -d= -f2- | tr -d '"') + if [[ -n "$PROD_ENC_SECRET" ]]; then + export NEXT_PUBLIC_ENCRYPTION_SECRET="$PROD_ENC_SECRET" + log "✅ 已注入生产加密密钥到构建环境" + else + log "⚠️ .env.production 中未找到 NEXT_PUBLIC_ENCRYPTION_SECRET,请检查配置" + fi + else + log "⚠️ 未找到 .env.production,无法注入生产加密密钥" + fi + if [[ "$CLEAN_BUILD" == "1" ]]; then npm run build:clean else