首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

  • 24-12-06 00:26
  • 4668
  • 76354
juejin.cn

背景

在最近临时支持的项目中,发现项目的构建流程耗时比较长,严重的影响了开发的进度。参照文档要发测试环境的时候,发现10分钟过去了还没有发布完成。项目是通过Docker来构建镜像部署的,所以想看看有没有什么方案,可以对Docker镜像构建进行优化。

现状

Dockerfile是长这样子的:

Dockfile文件分析

以下主要分析Dockerfile构建过程中主要执行的操作

一、基础镜像选择

首先定义了一个基础镜像FROM node:20.18.1-alpine AS base,这里选择了基于Alpine系统的Node.js版本20.18.1作为基础镜像。

二、依赖安装阶段(deps)

  1. 基于base镜像创建了deps镜像。
  2. 执行RUN apk add --no - cache libc6 - compat,这是在Alpine系统下安装libc6 - compat库,--no - cache表示不使用缓存。
  3. 将package.json、yarn.lock*、package - lock.json*、pnpm - lock.yaml*复制到当前工作目录(/app)。
  4. 根据不同的lock文件类型进行依赖安装:如果存在yarn.lock文件,执行yarn --frozen - lockfile,这是使用Yarn安装依赖并且确保使用lock文件中的版本,以保证可重复性。如果存在package - lock.json文件,执行npm ci,这是使用npm安装依赖并且确保按照package - lock.json中的版本精确安装。如果存在pnpm - lock.yaml文件,先全局安装pnpm(yarn global add pnpm),然后执行pnpm i --frozen - lockfile,同样是按照lock文件安装依赖。如果没有找到任何lock文件,则输出Lockfile not found.并以错误码1退出。

三、构建阶段(builder)

  1. 基于base镜像创建builder镜像。
  2. 从deps镜像复制/app/node_modules到当前工作目录下的node_modules。
  3. 复制当前目录(.)下的所有文件到/app。
  4. 执行yarn build:test,可能是使用Yarn构建测试版本的项目。

四、运行阶段(runner)

  1. 基于base镜像创建runner镜像。
  2. 设置环境变量NODE_ENV为production,表示生产环境。
  3. 从builder镜像复制/app/public到当前工作目录下的public。
  4. 从builder镜像复制/app/.next/standalone到当前工作目录下
  5. 从builder镜像复制/app/.app/.next/static到当前工作目录下的.next/static

构建镜像

通过运行Docker build的命令,我们可以看着在构建镜像的过程中,主要做了什么操作,每个操作耗时分别是多少:

可以看出,Docker镜像打包过程总共花费了614.6s,主要耗时集中在以下几个操作上:

  1. [internal] load metadata for docker.io/library/node:20.18.1-alpine: 4.4s
  2. => [internal] load build context: 23.8s
  3. => transferring context: 712.33MB: 23.8s
  4. => [deps 1/4] RUN apk add --no-cache libc6-compat: 3.0s
  5. => [deps 4/4] RUN if [ -f yarn.lock ]; then yarn --frozen-lockfile; elif [ -f package-lock.json ]; then npm ci; eli : 258.1s
  6. => [builder 2/4] COPY --from=deps /app/node_modules ./node_modules: 35.9s
  7. => [builder 3/4] COPY . .: 4.7s
  8. => [builder 4/4] RUN yarn build:test: 234.2s

优化

之前没有太多的Docker镜像打包经验,都是直接build写好的Dockerfile或者是基于开源的Dockerfile进行定制化开发(复制其他项目的拿过来改一下😊),所以搜了一下看看都有哪些优化的方案。单纯从Docker镜像打包来看,可以从以下几个方向入手:

  1. 使用更小的基础镜像
  2. 多阶段构建(Multi-stage Builds)
  3. 利用缓存加速构建
  4. 减少镜像层数
  5. 使用.dockerignore文件
  6. 分层打包(Layered Packaging)
  7. 静态二进制文件和“临时”基础映像

因为当前的项目已经做了1、2、6,所以我们还可以从4、5、7这三个方面考虑。

优化一:减少文件复制的时间

  1. 通过添加.dockerignore文件,过滤掉一些非必要的文件,来减少文件复制的时间。
  2. 我们看到之前的Dockerfile里,有一个复制node_modules的操作,花费了35.9s,可以想办法把这个去掉。

基于以上两点,对项目文件以及Dockerfile进行修改.

一、添加.dockerignore文件

内容如下:

bash
代码解读
复制代码
node_modules .next src/.DS_Store .vscode .husky

二、Dockerfile调整

三、构建看效果

我们可以看到,=> [builder 3/4] COPY . .从 4.7s 降到了 1.8s, => [builder 2/4] COPY --from=deps /app/node_modules ./node_modules 这一步的耗时已经没有了。

优化二:重新构建一个新的镜像作为基础镜像

通过观察Dockerfile,我们发现以node:20.18.1-alpine镜像为基础镜像进行构建的时候,还需要安装libc6-compat,受网络波动的影响libc6-compat有时候下载比较慢。那我们可以把在node:20.18.1-alpine环境下,下载好libc6-compat单独打包成一个镜像,上传到公司内部的镜像仓库中,直接使用这个新镜像来作为基础镜像就可以了。如何构建镜像上传到公司内部镜像仓库,大家可以去看看Docker的教程就可以了,这里就不展开了。

一、Dockerfile调整

二、构建效果

我们可以看到通过构建一个新的镜像上传到内部镜像仓库中使用,不仅镜像下载速度变快了,还可以节省下了 => [deps 1/4] RUN apk add --no-cache libc6-compat下载的时间。

  1. [internal] load metadata for docker.io/library/node:20.18.1-alpine: 4.4s => 0.7s
  2. => [internal] load build context: 23.8s => 11.3s
  3. => transferring context: 712.33MB: 23.8s => 9.9s
  4. => [deps 1/4] RUN apk add --no-cache libc6-compat: 3.0s => 0s

总结

由于是临时支持了这个项目,在对项目改动不大的情况下去进行了一些尝试,而且仅针对Docker镜像自身构建的优化。通过这次实践来看,这个项目单纯从Docker方面来进行优化,效果相对来说还是不够的,减少了70s左右的时间。整个构建耗时的流程还是在安装依赖以及项目本身的构建上,如果要想显著的提高项目发布速度,还得从这两方面入手。

其他

中间尝试还进行了npm包的下载速度优化,因为这个改动相对来说也比较小。配置国内的npm源,速度确实会提升不少,如果公司内部搭建有完整的私有npm仓库,那速度将会大大提升。

还有另外一种方案,就是利用Docker 多阶段构建来对依赖进行分批下载,下载完成之后再合并到一起进行打包构建,这样子也许可以节省一些时间。

注:本文转载自juejin.cn的奇舞精选的文章"https://juejin.cn/post/7444770696068743219"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

104
前端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top