From e44cdf913e16cca5b1e21c48035d16ce1a6d7a1f Mon Sep 17 00:00:00 2001 From: dekun Date: Wed, 10 Jun 2026 20:51:35 +0800 Subject: [PATCH] Switch deployment to npm and sync pnpm-lock.yaml with lunar-javascript. Use npm ci/install in deploy script and docs to avoid frozen pnpm lockfile failures on the server. Co-authored-by: Cursor --- README.md | 4 ++-- docs/DEPLOY.md | 25 +++++++++++++------------ pnpm-lock.yaml | 36 +++++++++++++++++++++++++++++++----- scripts/deploy.sh | 4 ++-- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 4ce001b..0b4d3db 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,8 @@ pnpm run dev ```bash cd /opt/zhimingge cp .env.example .env.local && nano .env.local # 填写 OPENAI_API_KEY,PORT=3130 -pnpm install --frozen-lockfile -pnpm run build +npm install --frozen-lockfile +npm run build pm2 start ecosystem.config.cjs pm2 save && pm2 startup ``` diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md index 24e0e1c..b44565b 100644 --- a/docs/DEPLOY.md +++ b/docs/DEPLOY.md @@ -72,14 +72,15 @@ node -v # 应 >= v20 npm -v ``` -### 3.3 安装 pnpm 与 PM2 +### 3.3 安装 PM2 ```bash -npm install -g pnpm pm2 -pnpm -v +npm install -g pm2 pm2 -v ``` +> **说明**:项目使用 **npm** + `package-lock.json` 安装依赖(无需 pnpm)。若已安装 pnpm 也可改用 `npm install`,避免 `pnpm-lock.yaml` 不同步问题。 + ### 3.4 安装 Git ```bash @@ -191,13 +192,13 @@ chmod 600 .env.local ```bash cd /opt/zhimingge -pnpm install --frozen-lockfile +npm ci || npm install ``` ### 7.2 生产构建 ```bash -pnpm run build +npm run build ``` 构建成功后生成 `.next/standalone/` 独立运行包。 @@ -217,7 +218,7 @@ cp -r public .next/standalone/public cp -r content .next/standalone/content ``` -> **说明**:若应用从项目根目录读取 `content/`,PM2 的 `cwd` 应设为 `/opt/zhimingge` 而非 standalone 子目录。当前 `ecosystem.config.cjs` 使用项目根目录 + `pnpm start`,构建后也可改用 standalone 的 `server.js`(见 7.5 备选方案)。 +> **说明**:若应用从项目根目录读取 `content/`,PM2 的 `cwd` 应设为 `/opt/zhimingge` 而非 standalone 子目录。当前 `ecosystem.config.cjs` 使用项目根目录 + `npm start`,构建后也可改用 standalone 的 `server.js`(见 7.5 备选方案)。 ### 7.4 使用 PM2 启动(推荐方式) @@ -330,10 +331,10 @@ cd /opt/zhimingge git pull origin main # 安装新依赖(如有变更) -pnpm install --frozen-lockfile +npm ci || npm install # 重新构建 -pnpm run build +npm run build # 若使用 standalone 复制方式,重新复制 static/public/content cp -r .next/static .next/standalone/.next/static @@ -419,7 +420,7 @@ curl https://op.bz121.com/v1/models \ 1. **`.env.local` 权限** 设为 `600`,勿提交 Git 2. **API Key** 仅保存在服务器,不要写入前端代码 3. 生产环境使用 **Nginx + HTTPS** -4. 定期 `apt update` 与 `pnpm update` +4. 定期 `apt update` 与 `npm update` 5. 若后续改为非 root 运行,创建专用用户: ```bash @@ -437,13 +438,13 @@ chown -R zhimingge:zhimingge /opt/zhimingge cd /opt && git clone https://git.bz121.com/dekun/zhimingge.git zhimingge cd /opt/zhimingge cp .env.example .env.local && nano .env.local -pnpm install --frozen-lockfile -pnpm run build +npm ci || npm install +npm run build pm2 start ecosystem.config.cjs pm2 save && pm2 startup # 日常更新 -cd /opt/zhimingge && git pull && pnpm install && pnpm run build && pm2 restart zhimingge +cd /opt/zhimingge && git pull && npm ci && npm run build && pm2 restart zhimingge # 查看状态 pm2 status && curl -I http://127.0.0.1:3130 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09e8af3..16ba8e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: lucide-react: specifier: ^0.468.0 version: 0.468.0(react@18.3.1) + lunar-javascript: + specifier: ^1.7.7 + version: 1.7.7 next: specifier: 15.1.11 version: 15.1.11(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -238,67 +241,79 @@ packages: resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.0.4': resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.0.4': resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.33.5': resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.33.5': resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.33.5': resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} @@ -362,24 +377,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@15.1.9': resolution: {integrity: sha512-uZ1HazKcyWC7RA6j+S/8aYgvxmDqwnG+gE5S9MhY7BTMj7ahXKunpKuX8/BA2M7OvINLv7LTzoobQbw928p3WA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@15.1.9': resolution: {integrity: sha512-gQIX1d3ct2RBlgbbWOrp+SHExmtmFm/HSW1Do5sSGMDyzbkYhS2sdq5LRDJWWsQu+/MqpgJHqJT6ORolKp/U1g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@15.1.9': resolution: {integrity: sha512-fJOwxAbCeq6Vo7pXZGDP6iA4+yIBGshp7ie2Evvge7S7lywyg7b/SGqcvWq/jYcmd0EbXdb7hBfdqSQwTtGTPg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@15.1.9': resolution: {integrity: sha512-crfbUkAd9PVg9nGfyjSzQbz82dPvc4pb1TeP0ZaAdGzTH6OfTU9kxidpFIogw0DYIEadI7hRSvuihy2NezkaNQ==} @@ -787,6 +806,7 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1389,6 +1409,7 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true globals@14.0.0: @@ -1688,6 +1709,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + lunar-javascript@1.7.7: + resolution: {integrity: sha512-u/KYiwPIBo/0bT+WWfU7qO1d+aqeB90Tuy4ErXenr2Gam0QcWeezUvtiOIyXR7HbVnW2I1DKfU0NBvzMZhbVQw==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -3639,7 +3663,7 @@ snapshots: '@typescript-eslint/parser': 8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3) eslint: 9.18.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.18.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.18.0(jiti@1.21.7)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.18.0(jiti@1.21.7)) eslint-plugin-react: 7.37.3(eslint@9.18.0(jiti@1.21.7)) @@ -3663,7 +3687,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.18.0(jiti@1.21.7)): + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -3679,14 +3703,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.18.0(jiti@1.21.7)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3) eslint: 9.18.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.18.0(jiti@1.21.7)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color @@ -3701,7 +3725,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.18.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.18.0(jiti@1.21.7)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)))(eslint@9.18.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -4259,6 +4283,8 @@ snapshots: dependencies: react: 18.3.1 + lunar-javascript@1.7.7: {} + math-intrinsics@1.1.0: {} mdast-util-from-markdown@2.0.2: diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 235977f..21f0f72 100644 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -14,10 +14,10 @@ echo "==> 拉取最新代码..." git pull origin main echo "==> 安装依赖..." -pnpm install --frozen-lockfile +npm ci || npm install echo "==> 生产构建..." -pnpm run build +npm run build echo "==> 确保日志目录存在..." mkdir -p logs