秋栈博客

七月

前端应用在pipeline流水线中的构建优化

2022-11-13

一、Dockerfile注意事项

原Dockerfile
FROM node:16.13.1 AS builder
WORKDIR /workspace
COPY . .
RUN npm config set registry https://registry.npmmirror.com
RUN npm i

FROM registry.cn-hangzhou.aliyuncs.com/luna-dev/main-node-service:${ORI_TAG} AS dister

#FROM node:16.13.1
FROM registry.cn-hangzhou.aliyuncs.com/luna-middleware/node-alpine:v16.14.2
RUN rm -rf /main-node-service/app/view/
COPY --from=dister /main-node-service/app/view/ /main-node-service/app/view/
COPY --from=builder /workspace  /main-node-service
COPY --from=builder /workspace/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
WORKDIR /main-node-service
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 7001

上述Dockerfile可优化项:

  1. Docker构建缓存优化(重要):缓存生效有三个关键点

    1. 镜像父层没有发生变化
    2. 构建指令不变
    3. 添加文件校验和一致
    #优化前
    COPY . .
    RUN npm i
    #优化后
    COPY ./package.json .
    RUN npm i
    COPY . .
    

  2. 镜像层数优化:尽量把一些功能统一的命令合到一起,简而言之就是减少RUN出现的次数

    #优化前
    RUN npm config set registry https://registry.npmmirror.com
    RUN npm i
    #优化后
    RUN npm config set registry http://registry.npmmirror.com --global && \
        npm install
    

  3. 工作路径优化:为了清晰性和可靠性建议都使用绝对路径

    #优化前
    WORKDIR /main-node-service
    #优化后
    WORKDIR /home/luna/main-node-service/
    

  4. 网络请求优化:推荐用一些网络比较好的国内开源站点,这样可以节约时间、减少失败率

    #阿里云
    npm config set registry http://registry.npmmirror.com
    #腾讯云
    npm config set registry http://mirrors.cloud.tencent.com/npm/
    #华为云
    npm config set registry https://repo.huaweicloud.com/repository/npm/
    
    http://npm.taobao.orghttp://registry.npm.taobao.org 将在 2022.06.30 号正式下线和停止 DNS 解析,服务域名切换规则请参考:
    http://npm.taobao.org => http://npmmirror.com
    http://registry.npm.taobao.org => http://registry.npmmirror.com
    
  5. 分阶段构建虽然能减少所构建镜像的大小,但是在此项目中基础镜像main-node-service更新频率低,分开编写更适用于本场景。

  6. ENTRYPOINT:

    • 如果Docker镜像的用途是运行应用程序或服务,比如运行一个Redis,应该优先使用exec格式的entrypoint指令,否则在某些情况下,这可能导致数据丢失或僵尸进程。
    • CMD可为entrypoint提供额外的默认参数,同时可利用docker run命令行替换默认参数。
    • 如果想为容器设置默认的启动命令,可使用cmd指令。用户可在docker run命令行中替换此默认命令。

二、示例

变更不频繁的应用单独拉出来:Dockerfile-base
ARG MAIN_NODE_VERSION
ARG APP_VERSION
#子应用
FROM registry.cn-hangzhou.aliyuncs.com/luna-dev/luna-mix-pc:${APP_VERSION} AS mix
FROM registry.cn-hangzhou.aliyuncs.com/luna-dev/luna-mainapp-pc:${APP_VERSION} AS mainapp
#COPY子应用到node应用镜像
FROM registry.cn-hangzhou.aliyuncs.com/luna-dev/main-node-service:${MAIN_NODE_VERSION}
COPY --from=mainapp /home/luna/mainapp-pc/main /home/luna/main-node-service/app/view/main
COPY --from=mix /home/luna/mix/mix  /home/luna/main-node-service/app/view/mix
变更频繁的应用Dockerfile优化:Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/luna-middleware/node-alpine:v16.14.2
#使用绝对路径
WORKDIR /home/luna/main-node-service/
#使用缓存,加速npm i
COPY ./package.json .
#合并功能命令
RUN npm config set registry http://registry.npmmirror.com --global && \
    npm config set disturl http://npmmirror.com/dist --global && \
    npm install
COPY . .
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 7001

三、优化成果:

以main-node-service为例

1、单次构建速度从整体 15 min缩短至 3 min以内,以每日10次提交为例预计能为开发人员节省出2小时的开发时间,极大提升开发效率。

2、运维人员能更好地设计流水线,理清逻辑,为公司节省大量人力、机器资源和时间。

  • 0