如何在Kubernetes生产环境部署附带dist目录的Node JS应用
问题根因
dist目录未打包进镜像的核心问题是配置逻辑不一致,有3处明显错误:
yarn build仅在Bitbucket CI的临时运行环境中执行,生成的dist目录存放在CI临时工作区,你当前的Dockerfile未主动将dist目录纳入镜像- 流水线步骤顺序倒置:先执行部署操作再构建镜像,可能导致部署旧版本镜像
- 全链路端口不匹配:Dockerfile暴露端口为8100、Service目标端口为7000,和Express实际监听端口不一致,即使dist打包成功也会出现访问异常
修复方案
1. 采用多阶段构建打包dist(兼顾安全性)
推荐使用Docker多阶段构建,所有构建依赖仅存在于构建阶段,最终运行镜像不会残留源码、构建缓存、开发依赖,大幅降低镜像体积和安全攻击面,同时避免CI环境和镜像环境差异导致的dist生成异常。
# 构建阶段:仅用于生成dist,所有开发依赖不会进入最终镜像 FROM node:14.17.0 AS builder WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile COPY . . RUN yarn build # 运行阶段:仅保留运行所需的最小文件 FROM node:14.17.0-slim WORKDIR /app # 仅复制必要文件,不要复制完整源码目录避免源码泄露 COPY --from=builder /app/package.json ./ COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY --from=builder /app/app.js ./ # 生产环境配置 ENV NODE_ENV production # 和Express实际监听端口、K8s Service目标端口对齐 EXPOSE 7000 # 用非root用户运行容器,降低容器被攻破后的权限风险 USER node CMD ["node", "app.js"]
如果业务要求必须在CI环节生成dist,可保留CI中的yarn build步骤,在Dockerfile中新增COPY dist ./dist即可,无需在Dockerfile中执行构建操作。
2. 调整Bitbucket流水线步骤
修正步骤顺序,镜像推送成功后再执行部署,避免部署失效:
options: docker: true image: node:14.17.0 pipelines: branches: test: - step: services: - docker name: Build and push new docker image deployment: dev script: - yarn install - yarn test - yarn lint - docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD - docker build -t testapp/helloapp:latest -f ./Dockerfile . - docker push testapp/helloapp # 镜像推送成功后再执行部署 - make deploy.dev caches: - docker - node # 新增node缓存加快CI依赖安装速度
3. 对齐K8s配置
你当前的Service配置targetPort为7000,确保和Express实际监听端口、Dockerfile暴露端口完全一致即可,无需额外修改。
额外安全建议
- 敏感配置全部通过K8s Secret/ConfigMap注入,不要硬编码在镜像或代码中
- 定期扫描基础镜像的CVE漏洞,建议将node:14.17.0升级到当前LTS版本的slim镜像
- 给镜像打版本号标签而非仅使用latest,方便版本回滚,避免镜像被意外覆盖导致部署异常
- Docker Hub认证信息已经使用Bitbucket保密变量存储,不要修改为明文配置
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

