Docker 安装 Node.js
Node 镜像怎么选、生产镜像怎么写、node_modules 怎么处理。
Key Points选 alpine 还是 slim 看原生依赖:alpine 用 musl,有些包要重新编译;生产用多阶段 + npm ci --omit=dev。
直接跑
Bash
docker run -it --rm -v "$PWD:/app" -w /app node:20-alpine sh
node -v
npm -v生产 Dockerfile
Dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]镜像怎么选
| Tag | Size | When |
|---|---|---|
node:20 | ~1.1GB | Debugging, needs build tools |
node:20-slim | ~200MB | glibc native modules |
node:20-alpine | ~130MB | Small, musl — some modules need rebuilding |
node:20-alpine + distroless | ~110MB | Hardened production |
node_modules 的三个坑
- 宿主目录挂载会盖掉容器里的
node_modules→ 加匿名卷-v /app/node_modules .dockerignore不排除node_modules,构建上下文会大到几百 MB- alpine 里
sharp、bcrypt等原生模块要装python3 make g++才能编译
Bash
# 开发时热更新
docker run -d --name dev -p 3000:3000 \
-v "$PWD:/app" -v /app/node_modules \
-w /app node:20-alpine npm run devUse
npm ci, not npm install: the former installs exactly what package-lock.json says, so builds are reproducible.直接跑
Bash
docker run -it --rm -v "$PWD:/app" -w /app node:20-alpine sh
node -v
npm -v生产 Dockerfile
Dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]镜像怎么选
| 标签 | 体积 | 何时用 |
|---|---|---|
node:20 | ~1.1GB | 调试、需要编译工具 |
node:20-slim | ~200MB | 依赖 glibc 的原生模块 |
node:20-alpine | ~130MB | 体积小,musl,部分模块要重编 |
| distroless | ~110MB | 安全加固的生产环境 |
node_modules 的三个坑
- 宿主目录挂载会盖掉容器里的
node_modules→ 加匿名卷-v /app/node_modules .dockerignore不排除node_modules,构建上下文会大到几百 MB- alpine 里
sharp、bcrypt等原生模块要装python3 make g++才能编译
Bash
# 开发时热更新
docker run -d --name dev -p 3000:3000 \
-v "$PWD:/app" -v /app/node_modules \
-w /app node:20-alpine npm run dev用
npm ci 而不是 npm install:前者严格按 package-lock.json 安装,构建可复现;后者可能悄悄升级依赖。