在使用typescript编写基于node.js的微服务项目时,需要将服务以docker形式进行发布,遇到了一些问题,现在记录一下。
docker镜像使用的node版本与开发版本不一致,会导致很多问题。在开发时,使用的是完整版本,而在部署时,希望使用简化版本以减小尺寸。版本不一致会使开发过程中npm module与创建容器时的版本不同,从而导致错误。有几点需要注意:
1、需要使用npm install 而不是npm ci,并且只复制package.json到容器。
这是因为npm ci会严格按照package-lock.json进行部署,而这是获取的npm modules是与开发环境相匹配的,不一定适合创建容器的简化版本。
2、使用相近的node简化版本,尽量减少开发与部署的版本差别。
3、可能需要在docker部署时安装python和其它辅助程序包。
简单部署时,可以将源代码拷入,直接生成,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # 使用 Node.js 官方镜像作为基础镜像 FROM node:18-alpine
WORKDIR /app
# 复制 package.json 和 package-lock.json(如果存在) COPY package.json ./
# 安装依赖 RUN npm install
# 复制源代码 COPY . .
# 构建 TypeScript 代码 RUN npm run build
# 暴露端口 EXPOSE 3000
CMD ["node", "dist/app.js"]
|
复杂情况下,可以先进行编译,然后创建部署容器。下面是复杂情况下的Dockerfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| # 构建阶段:安装依赖并编译 FROM node:20.10.0 AS builder
WORKDIR /app
# 复制并安装依赖 COPY package.json ./ RUN npm install
# 复制源码并构建 COPY . . RUN npm run build
# 生产阶段:仅保留必要内容 FROM node:20-alpine
# 启用仓库并安装工具链 RUN echo "https://dl-cdn.alpinelinux.org/alpine/v3.18/main" > /etc/apk/repositories && \ echo "https://dl-cdn.alpinelinux.org/alpine/v3.18/community" >> /etc/apk/repositories && \ apk update && \ apk add --no-cache build-base python3
WORKDIR /app
# 复制生产依赖清单 COPY package.json ./ COPY data ./data
# 安装生产依赖(不包含devDependencies) RUN npm install --production
# 从构建阶段复制编译结果 COPY --from=builder /app/dist ./dist
# 暴露端口 EXPOSE 3000
# 启动命令 CMD ["node", "dist/app.js"]
|