docs: Node Dockerfile hard rules (NODE_ENV, heap, serialize stages)

This commit is contained in:
gitea-robot
2026-07-31 20:15:15 +08:00
parent 0719e4fa2d
commit 520c121176
2 changed files with 68 additions and 15 deletions

View File

@@ -123,6 +123,10 @@ MCP endpoint`https://company-deploy-mcp.loncode.site/mcp`
- 识别栈;保证 Dockerfile`.gitignore` 排除密钥 - 识别栈;保证 Dockerfile`.gitignore` 排除密钥
- 有状态:默认 `/data`;多目录用 `persistence[]` - 有状态:默认 `/data`;多目录用 `persistence[]`
- 需要库:`databases: [{ engine: "postgres"|"mysql", ... }]` - 需要库:`databases: [{ engine: "postgres"|"mysql", ... }]`
- **Node 多阶段硬规则**(详见 `stack-profiles.md`
- 禁止在 `npm ci`/`pnpm install` **之前** `ENV NODE_ENV=production`(否则 `nest`/`vite` not found
- 大前端 Vite`NODE_OPTIONS=--max-old-space-size=3072`
- runtime 用 `COPY --from=build` 串行,避免并行双 `npm ci` 把小机打爆
### 2. 仓库与推送(权限红线) ### 2. 仓库与推送(权限红线)
@@ -299,6 +303,8 @@ Agent **不要**在 MCP 路径下再调 Dokploy `domain.create`(避免双绑/
|------|------| |------|------|
| 401 / 要 Feishu Key | 引导连接中心登录,配置 `buxi_` | | 401 / 要 Feishu Key | 引导连接中心登录,配置 `buxi_` |
| git push 权限 / Permission denied / 要配 SSH | **错误路径**。改用 `ensure_repository``agentHint.pushUrl` 推送;禁止给用户配 SSH | | git push 权限 / Permission denied / 要配 SSH | **错误路径**。改用 `ensure_repository``agentHint.pushUrl` 推送;禁止给用户配 SSH |
| `nest: not found` / `vite: not found` | build 阶段在装依赖前设了 `NODE_ENV=production`;先全量 `npm ci` 再设 production |
| `JavaScript heap out of memory` | Dockerfile build 加 `NODE_OPTIONS=--max-old-space-size=3072`;避免并行 npm ci机器内存过小则升配 |
| 运行中项目达上限 | `get_my_quota`;停/删旧应用后再部署 | | 运行中项目达上限 | `get_my_quota`;停/删旧应用后再部署 |
| Forbidden 看他人项目 | 非管理员;加 `ADMIN_OPEN_IDS` 或只查自己的 | | Forbidden 看他人项目 | 非管理员;加 `ADMIN_OPEN_IDS` 或只查自己的 |
| 有部署无 HTTPS | 等 LE查 DNS/80控制面证书配置 | | 有部署无 HTTPS | 等 LE查 DNS/80控制面证书配置 |

View File

@@ -113,43 +113,90 @@ CMD ["uv", "run", "your-entrypoint"]
检测:`package.json`,优先 `pnpm-lock.yaml``package-lock.json``yarn.lock` 检测:`package.json`,优先 `pnpm-lock.yaml``package-lock.json``yarn.lock`
推荐结构standalone / 需 `node` 运行): ### Dockerfile 硬规则踩过的坑Agent 必守)
| 错误 | 现象 | 正确做法 |
|------|------|----------|
| 在 **build 阶段 `npm ci` 之前** `ENV NODE_ENV=production` | `nest: not found` / `vite: not found`;日志里 packages 只有几百个(缺 devDependencies | **先** `npm ci`(装全量含 dev**再** `ENV NODE_ENV=production``npm run build` |
| 不设 Node 堆、大前端 Vite 打包 | `FATAL ERROR: JavaScript heap out of memory` | build 阶段:`ENV NODE_OPTIONS=--max-old-space-size=3072`(小机 34G 可试 2560 |
| multi-stage 里 **build 与 runtime 无依赖** | Docker **并行** 两个 `npm ci`,小机内存翻倍易 OOM | runtime 至少 `COPY --from=build …` 一件产物,让 build 先完成 |
| 用用户 SSH 推 Gitea | Permission denied | 用 `ensure_repository``pushUrl`,见 SKILL |
### 推荐Nest + Vite 全栈模板
```dockerfile ```dockerfile
FROM node:22-bookworm-slim AS deps
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
# 可选COPY .npmrc ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
FROM node:22-bookworm-slim AS build FROM node:22-bookworm-slim AS build
WORKDIR /app WORKDIR /app
# ① 提高堆;② 此时不要 NODE_ENV=production
ENV NODE_OPTIONS=--max-old-space-size=3072
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
COPY . ./
# ③ 仅编译时 production
ENV NODE_ENV=production
RUN npm run build:prod && npm cache clean --force
FROM node:22-bookworm-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production \
SERVER_HOST=0.0.0.0 \
SERVER_PORT=3000 \
DATA_DIR=/data
COPY package.json package-lock.json ./
# ④ 依赖 build避免与 vite 并行 npm ci
COPY --from=build /app/package.json /tmp/.build-done
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force
COPY --from=build /app/dist ./
EXPOSE 3000
CMD ["node", "server/main.js"]
```
### 推荐:较轻的 Node APIpnpm
```dockerfile
FROM node:22-bookworm-slim AS build
WORKDIR /app
ENV NODE_OPTIONS=--max-old-space-size=2048
RUN corepack enable RUN corepack enable
COPY --from=deps /app/node_modules ./node_modules COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile
COPY . . COPY . .
ENV NODE_ENV=production
RUN pnpm run build RUN pnpm run build
FROM node:22-bookworm-slim AS runner FROM node:22-bookworm-slim AS runner
WORKDIR /app WORKDIR /app
ENV NODE_ENV=production ENV NODE_ENV=production DATA_DIR=/data
ENV DATA_DIR=/data
COPY --from=build /app/dist ./dist COPY --from=build /app/dist ./dist
COPY --from=build /app/package.json ./ COPY --from=build /app/package.json ./
COPY --from=deps /app/node_modules ./node_modules COPY --from=build /app/node_modules ./node_modules
# 若 node_modules 含 dev可改为 runner 单独 pnpm install --prod
EXPOSE 3000 EXPOSE 3000
CMD ["node", "dist/index.js"] CMD ["node", "dist/index.js"]
``` ```
静态前端Vite 等)可用 `nginx:stable-alpine``dist``spec.port` 多为 `80` 静态前端Vite 等)可用 `nginx:stable-alpine``dist``spec.port` 多为 `80`
纯静态站构建同样需要 **devDependencies**vite在 build 阶段装全。
Registry 加速示例 `.npmrc`(可提交或构建时注入) Registry 加速示例 `.npmrc`
```ini ```ini
registry=https://registry.npmmirror.com registry=https://registry.npmmirror.com
``` ```
### 部署前 Agent 自检Node
- [ ] Dockerfile **没有**在安装依赖前设置 `NODE_ENV=production`
- [ ] `nest` / `vite` / `tsc` 等 CLI 在 **devDependencies** 且 build 阶段能装到
- [ ] 大前端:`NODE_OPTIONS=--max-old-space-size=3072`(或更高,视机器)
- [ ] multi-stageruntime 依赖 build避免并行双 `npm ci`
- [ ] 运行 `CMD` 只跑编译产物,**不**在 runtime 再 `nest build`
--- ---
## Docker Compose ## Docker Compose