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

@@ -113,43 +113,90 @@ CMD ["uv", "run", "your-entrypoint"]
检测:`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
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
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
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 . .
ENV NODE_ENV=production
RUN pnpm run build
FROM node:22-bookworm-slim AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV DATA_DIR=/data
ENV NODE_ENV=production DATA_DIR=/data
COPY --from=build /app/dist ./dist
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
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
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