使用构建缓存优化 Docker 镜像构建
使用构建缓存优化 Docker 镜像构建
目录
- 实践
- 构建应用程序
- 额外资源
- 后续步骤
假设一个简单的nodejs程序的 Dockerfile如下:
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "./src/index.js"]
当你运行 docker build 命令来创建新镜像时,Docker 会按指定顺序执行 Dockerfile 中的每条指令,为每个命令创建一个层。对于每条指令,Docker 会检查是否可以重用之前构建中的指令。如果发现之前已经执行过类似的指令,Docker 就不需要重新执行,而是使用缓存的结果。这样,你的构建过程会变得更快、更高效,节省宝贵的时间和资源。
有效使用构建缓存可以通过重用之前构建的结果并跳过不必要的工作来实现更快的构建。为了最大化缓存的使用并避免资源密集型和耗时的重建,理解缓存失效的工作原理非常重要。以下是一些可能导致缓存失效的情况:
RUN指令的任何更改 会使该层失效。如果Dockerfile中的RUN命令有任何修改,Docker会检测到变化并使构建缓存失效。- 使用
COPY或ADD指令复制到镜像中的文件的任何更改。Docker会监视项目目录中的任何更改,无论是内容的变化还是属性(如权限)的变化,Docker都会将这些修改视为触发缓存失效的原因。 - 一旦某一层失效,所有后续层也会失效。如果由于更改导致任何之前的层(包括基础镜像或中间层)失效,
Docker会确保依赖于它的后续层也失效。这保持了构建过程的同步,防止不一致。
在编写或编辑 Dockerfile 时,注意避免不必要的缓存失效,以确保构建尽可能快速和高效地进行。
实践
在本指南中,你将学习如何有效使用 Docker 构建缓存来优化 Node.js 应用程序的构建过程。
构建应用程序
下载并安装 Docker Desktop。
打开终端并克隆这个示例应用程序:
git clone https://github.com/dockersamples/todo-list-app
进入 todo-list-app 目录:
cd todo-list-app
在这个目录中,你会找到名为 Dockerfile 的文件,内容如下:
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
EXPOSE 3000
CMD ["node", "./src/index.js"]
执行以下命令来构建 Docker 镜像:
docker build .
构建过程如下所示:
[+] Building 20.0s (10/10) FINISHED
第一行表示整个构建过程花费了 20.0 秒。第一次构建可能会花费一些时间,因为需要安装依赖项。
不做任何更改进行重建
现在,在不更改源代码或 Dockerfile 的情况下重新运行 docker build 命令:
docker build .
后续构建由于缓存机制而变得更快,只要命令和上下文保持不变。Docker 会缓存构建过程中生成的中间层。当你在不更改 Dockerfile 或源代码的情况下重新构建镜像时,Docker 可以重用缓存的层,从而显著加快构建过程。
[+] Building 1.0s (9/9) FINISHED
后续构建仅在 1.0 秒内完成,通过利用缓存层,无需重复耗时的步骤,如安装依赖项。
| 步骤 | 描述 | 第一次运行时间 | 第二次运行时间 |
|---|---|---|---|
| 1 | 从 Dockerfile 加载构建定义 | 0.0 秒 | 0.0 秒 |
| 2 | 加载 docker.io/library/node:20-alpine 的元数据 | 2.7 秒 | 0.9 秒 |
| 3 | 加载 .dockerignore | 0.0 秒 | 0.0 秒 |
| 4 | 加载构建上下文 (上下文大小: 4.60MB) | 0.1 秒 | 0.0 秒 |
| 5 | 设置工作目录 (WORKDIR) | 0.1 秒 | 0.0 秒 |
| 6 | 将本地代码复制到容器中 | 0.0 秒 | 0.0 秒 |
| 7 | 运行 yarn install --production | 10.0 秒 | 0.0 秒 |
| 8 | 导出层 | 2.2 秒 | 0.0 秒 |
| 9 | 导出最终镜像 | 3.0 秒 | 0.0 秒 |
优化 Dockerfile
为了避免每次构建都重新安装相同的依赖项,可以重新组织 Dockerfile 以保持依赖项缓存的有效性,除非确实需要使其失效。对于基于 Node 的应用程序,依赖项定义在 package.json 文件中。你可以在该文件更改时重新安装依赖项,但如果文件未更改,则使用缓存的依赖项。因此,首先复制 package.json 文件,然后安装依赖项,最后复制其他所有内容。这样,只有在 package.json 文件更改时才需要重新创建 yarn 依赖项。
更新 Dockerfile 以首先复制 package.json 文件,安装依赖项,然后复制其他所有内容:
FROM node:20-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production
COPY . .
EXPOSE 3000
CMD ["node", "src/index.js"]
在与 Dockerfile 相同的文件夹中创建一个名为 .dockerignore 的文件,内容如下:
node_modules
构建新镜像:
docker build .
输出如下:
[+] Building 16.1s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 175B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:21-alpine 0.0s
=> [internal] load build context 0.8s
=> => transferring context: 53.37MB 0.8s
=> [1/5] FROM docker.io/library/node:21-alpine 0.0s
=> CACHED [2/5] WORKDIR /app 0.0s
=> [3/5] COPY package.json yarn.lock ./ 0.2s
=> [4/5] RUN yarn install --production 14.0s
=> [5/5] COPY . . 0.5s
=> exporting to image 0.6s
=> => exporting layers 0.6s
=> => writing image
sha256:d6f819013566c54c50124ed94d5e66c452325327217f4f04399b45f94e37d25 0.0s
=> => naming to docker.io/library/node-app:2.0 0.0s
现在,修改 src/static/index.html 文件(例如将标题更改为 “The Awesome Todo App”)。
构建 Docker 镜像。此时,你的输出应有所不同:
docker build -t node-app:3.0 .
输出如下:
[+] Building 1.2s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:21-alpine 0.0s
=> [internal] load build context 0.2s
=> => transferring context: 450.43kB 0.2s
=> [1/5] FROM docker.io/library/node:21-alpine 0.0s
=> CACHED [2/5] WORKDIR /app 0.0s
=> CACHED [3/5] COPY package.json yarn.lock ./ 0.0s
=> CACHED [4/5] RUN yarninstall --production 0.0s
=> [5/5] COPY . . 0.5s
=> exporting to image 0.3s
=> => exporting layers 0.3s
=> => writing image
sha256:91790c87bcb096a83c2bd4eb512bc8b134c757cda0bdee4038187f98148e2eda 0.0s
=> => naming to docker.io/library/node-app:3.0 0.0s
首先,你会注意到构建速度快了很多。你会看到多个步骤使用了之前缓存的层。这是个好消息;你正在使用构建缓存。推送和拉取此镜像及其更新也会快得多。
通过遵循这些优化技术,你可以加快 Docker 构建速度,提高开发效率,缩短迭代周期,提高开发生产力。
相关文章:
使用构建缓存优化 Docker 镜像构建
使用构建缓存优化 Docker 镜像构建 目录 实践构建应用程序额外资源后续步骤 假设一个简单的nodejs程序的 Dockerfile如下: FROM node:20-alpine WORKDIR /app COPY . . RUN yarn install --production CMD ["node", "./src/index.js"]当你运…...
微软搁置水下数据中心项目——项目纳蒂克相比陆地服务器故障更少
“我的团队努力了,并且成功了,”COI负责人诺埃尔沃尔什说。 微软已悄然终止了始于2013年的水下数据中心(UDC)项目“纳蒂克”。该公司向DatacenterDynamics确认了这一消息,微软云运营与创新部门负责人诺埃尔沃尔什表示…...
国产AI算力训练大模型技术实践
ChatGPT引领AI大模型热潮,国内外模型如雨后春笋,掀起新一轮科技浪潮。然而,国内大模型研发推广亦面临不小挑战。面对机遇与挑战,我们需保持清醒,持续推进技术创新与应用落地。 为应对挑战,我们需从战略高度…...
DS:二叉树的链式存储及遍历
欢迎来到Harper.Lee的学习世界! 博主主页传送门:Harper.Lee的博客主页 想要一起进步的uu可以来后台找我哦! 一、引入 1.1 二叉树的存储方式 在之前接触到的满二叉树和完全二叉树使用的是数组的存储方式(DS:树与…...
C#中File类常见用法总结
前言 我们在开发C#软件的过程中,经常需要和文件打交道,那么File类在C#中是我们使用非常频繁的一个类,本文就是详细介绍File类在C#中的常见用法。 1、判断文件是否存在 string fileName "1.txt";bool isExist File.Exists(fileN…...
CesiumJS【Basic】- #007 绘制直线段以避免地球曲率的影响
文章目录 绘制直线段以避免地球曲率的影响1 目标2 实现绘制直线段以避免地球曲率的影响 1 目标 绘制直线段以避免地球曲率的影响 2 实现 在CesiumJS中,直线的弯曲是由地球曲率引起的,因为地球是一个球体而不是一个平面。因此,如果您要在地球上绘制两点之间的直线,它将会…...
解决文件或文件夹无法删除问题
最近呢,发现很多小伙伴都会遇到一个问题,就是当我要删掉一个文件或者软件的时候,就会弹出[操作无法完成,因为其中的文件夹或文件已在另一个程序中打开] 然后我就翻看网站,很多都是什么去**[任务管理器]修改[资源管理器…...
【报错】JDBC SQL语句表名报错 解决办法
解决办法 修改检测等级 不是检测有问题吗,那就将idea的检测问题取消掉或者修改检测问题等级,根本问题上我们写的sql语句是一个字符串传过去,只要在mysql查询语句能够正确执行,不要这种检测也罢。...
【Nvidia+AI摄像头】面向机器人双目视觉相机
随着人工智能和机器人技术的不断发展,双目深度相机作为一种重要的传感器,正在被广泛应用于各种机器人系统中。双目深度相机作为机器人不可或缺的感知器件,其高精度深度信息为机器人提供环境感知、立体视觉、姿态识别等功能,让机器…...
Hive数据锁问题处理
在测试环境有定时任务会定期将flume采集的数据load到hive表中,在查看yarn application过程中发现load操作没有执行,且后续的任务在上一个任务执行结束后很久才开始。感觉像是阻塞一样,于是手动执行相关脚本,发现也是会卡住&#x…...
使用VisualBox+Vagrant搭建Centos虚拟机环境
1.下载并安装VisualBox; 2.下载并安装Vagrant; 3.打开cmd窗口,执行命令vagrant init centos/7,初始化centos环境,该步骤受网络带宽影响,可能挂级30分钟到1个小时; 4.启动虚拟机:vagrant up&…...
PHP框架之Yii框架
Yii框架详细说明 Yii框架是一个基于组件的高性能PHP框架,用于开发大型Web应用。Yii框架由薛强创立,自2008年1月1日开始开发,至今已成为PHP开发领域的佼佼者之一。Yii框架以其高效、安全、灵活和可扩展的特性,赢得了众多开发者的青…...
数组元素去重
1 .旧数组不重复的元素放到新数组 2 .遍历旧数组,拿旧数组查新数组,如果元素在新数组内没有出现过就添加 3 .利用 新数组.indexOf(数组元素) 如果返回-1就说明新数组里没有该元素 //封装一个 去重的函数 function unique(arr) {var newArr[];for(var …...
Redis 的安装与部署
本文为Redis的Linux版单机部署。 上传 redis-3.2.8 源码到 /opt/software/ 解压到 /opt/module/ [huweihadoop101 software]$ tar -zxvf redis-3.2.8.tar.gz -C /opt/module/安装依赖 [huweihadoop101 software]$ sudo yum -y install gcc-c tclRedis是C语言编写的 编译安装…...
Applied Spatial Statistics(七):Python 中的空间回归
Applied Spatial Statistics(七):Python 中的空间回归 本笔记本演示了如何使用 pysal 的 spreg 库拟合空间滞后模型和空间误差模型。 OLS空间误差模型空间滞后模型三种模型的比较探索滞后模型中的直接和间接影响 import numpy as np impor…...
如何关闭软件开机自启,提升电脑开机速度?
如何关闭软件开机自启,提升电脑开机速度?大家知道,很多软件在安装时默认都会设置为开机自动启动。但是,有很多软件在我们开机之后并不是马上需要用到的,开机启动的软件过多会导致电脑开机变慢。那么,如何关…...
如何培养员工的竞争意识
一、背景 在当今快速变化的商业环境中,培养员工的竞争意识对于企业的长期成功至关重要。通过激发员工的竞争精神,企业能够提升整体绩效,增强创新能力,并在市场竞争中保持领先地位。本文将从多个方面探讨如何培养员工的竞争意识。 二、明确目标设定 设定清晰具体的目标:明…...
2025秋招NLP算法面试真题(二)-史上最全Transformer面试题:灵魂20问帮你彻底搞定Transformer
简单介绍 之前的20个问题的文章在这里: https://zhuanlan.zhihu.com/p/148656446 其实这20个问题不是让大家背答案,而是为了帮助大家梳理 transformer的相关知识点,所以你注意看会发现我的问题也是有某种顺序的。 本文涉及到的代码可以在…...
redis初步认识(一)
文章目录 概述安装编译 string数据结构基础命令应用对象存储累加器 list结构基础命令应用栈(先进后出FILO)队列 HASH基础命令存储结构应用存储对象 小结 概述 redis 是一个远程字典服务;当然,redis是内存数据库,kv数据库,最基础的…...
Android 开发必备知识点及面试题汇总(Android+Java+算法+性能优化+四大组件……
**虚引用:**顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。 7.介绍垃圾回收机制 **标记回收法:**遍历对象图并且记录可到达的对象,…...
解锁端侧智能:基于BigDL-LLM与Qwen-1.8B-Chat的CPU高效推理实践
1. 为什么要在CPU上部署大模型? 最近两年大模型技术发展迅猛,但大多数应用都依赖昂贵的GPU服务器。我在实际项目中发现,很多中小企业和个人开发者其实更需要能在普通电脑上运行的轻量化方案。这就是为什么基于CPU的大模型部署方案变得越来越…...
低温预警!固化慢、易开裂……密封胶冬季施工手册
低温预警!固化慢、易开裂……密封胶冬季施工手册 硅酮耐候密封胶主要作用是保障幕墙的气密性、水密性。其出现问题,可能会导致耐候密封失效,从而造成幕墙漏水漏气,影响幕墙的正常使用。耐候密封胶由于考虑到现场施工,几乎都是单组分硅酮密封胶产品。进入冬季,气候变化明…...
Windows驱动清理终极指南:用DriverStore Explorer安全释放数十GB磁盘空间
Windows驱动清理终极指南:用DriverStore Explorer安全释放数十GB磁盘空间 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 你的Windows电脑是否经常提示C盘空间不足ÿ…...
番茄小说下载器:打造属于你的个人数字图书馆终极指南
番茄小说下载器:打造属于你的个人数字图书馆终极指南 【免费下载链接】fanqienovel-downloader 下载番茄小说 项目地址: https://gitcode.com/gh_mirrors/fa/fanqienovel-downloader 你是否曾经遇到过这样的场景?深夜追更小说时网络突然断线&…...
服务网格Istio实战
服务网格Istio实战 引言 服务网格(Service Mesh)作为微服务架构的基础设施层,提供了对服务间通信的精细控制能力。Istio是目前最流行的开源服务网格解决方案,它通过Sidecar代理拦截所有网络通信,提供流量管理、安全、可…...
Arm Fast Models中VGIC架构与中断虚拟化解析
1. Arm Fast Models中的VGIC架构解析虚拟通用中断控制器(Virtual Generic Interrupt Controller, VGIC)是Armv7/v8架构虚拟化扩展的核心组件之一。在Fast Models仿真环境中,Iris组件通过精确建模实现了VGIC的完整功能,包括:物理中断与虚拟中断…...
基于BLE信号强度的寻物游戏:用CircuitPython实现无线接近探测
1. 项目概述:一个用蓝牙信号“捉迷藏”的硬件游戏几年前我第一次接触Adafruit的Circuit Playground系列开发板时,就被它那种“开箱即玩”的理念吸引了。它把LED、按钮、传感器都集成在一块板子上,让你不用焊接就能快速验证想法。后来出的Circ…...
数据模型代码生成器:从OpenAPI/Schema自动生成Python类型安全模型
1. 项目概述:当数据模型遇上代码生成如果你经常和数据模型打交道,无论是OpenAPI规范、JSON Schema,还是数据库的DDL,那你一定体会过手动编写对应数据类(Data Class)或Pydantic模型的繁琐。一个字段类型写错…...
NoC路由设计与缓存一致性协议的协同优化
1. 项目概述:缓存一致性对NoC路由设计的挑战与机遇在当今多核处理器架构中,片上网络(NoC)作为核心间通信的基础设施,其设计质量直接影响整体系统性能。我曾在一次芯片设计项目中深刻体会到,当核心数量增加到64个时,传统…...
ctfileGet:城通网盘直连地址解析工具的技术原理与实用指南
ctfileGet:城通网盘直连地址解析工具的技术原理与实用指南 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet ctfileGet是一个基于Web的开源工具,专门用于解析城通网盘分享链接并获…...
