docker build高效利用cache

本文探讨了如何在DockerBuild过程中有效利用Cache机制提升构建效率。通过合理安排Dockerfile指令顺序,如将不变内容前置,频繁变更内容后置,可最大化Cache使用。文章还介绍了如何使用LABEL或MAINTAINER指令阻断Cache,确保指定步骤重新执行,以及如何通过--no-cache参数完全禁用Cache。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:docker build高效利用cache

前言

Dockerfile 可以通过docker build命令构建为一个新的镜像,Dockerfile 中每一条命令都会构建出一个新的镜像层。当你重新build相同的Docker时,Docker会逐条语句check自身的cache镜像层,如果命中相同的,就使用cache而不执行这条语句继续往下逐条check直至build完成。Docker build cache相关知识可以参考docker build 的 cache 机制

本文主要讲述如何利用cache提高build的效率。

正文

1. build Dockerfile 部分使用 cache

目前 docker 利用 cache 的基本原理是在父节点存在 cache 的前提下 当前 dockerfile 的那条语句之前也构建过就可以用 cache。例外就是 ADD 和 COPY 需要计算一个 checksum。 大致意思就是如果你中间有一层不能用 cache 那之后的层次就都不能用了。因此主要功夫在写 dockerfile 上,尽量把不变的内容放在前面,频繁变化的内容放在最后。简单说就是 把 ADD 和 COPY 的内容放最后一句,这样很多情况下只有最后一层变,前面都能用 cache。 比如我们在Dockerfile中使用了RUN go get xxx,我们提交了一下最新代码,然后重新build时,会命中cache,导致build出的image使用的还是之前的代码。

▶ docker build -t="jeorch/ddsaas:1.0.1" ./
Sending build context to Docker daemon  266.2kB
Step 1/8 : FROM golang:alpine
 ---> 20ff4d6283c0
Step 2/8 : RUN apk add --no-cache git mercurial
 ---> Using cache
 ---> 7c76541453d4
Step 3/8 : RUN go get github.com/alfredyang1986/blackmirror
 ---> Using cache
 ---> b8a5b7464bed
Step 4/8 : RUN go get github.com/alfredyang1986/ddsaas
 ---> Using cache
 ---> 27e569d1cdf5
Step 5/8 : ADD deploy-config/ /go/bin/
 ---> Using cache
 ---> 0a72ad21b21c
Step 6/8 : RUN go install -v github.com/alfredyang1986/ddsaas
 ---> Using cache
 ---> beda69880a63
Step 7/8 : WORKDIR /go/bin
 ---> Using cache
 ---> f57778461a26
Step 8/8 : ENTRYPOINT ["ddsaas"]
 ---> Using cache
 ---> 4c41a3140c4d
Successfully built 4c41a3140c4d
Successfully tagged jeorch/ddsaas:1.0.1

我们可以在Dockerfile中的RUN go get xxx之前添加一句标识来阻断cache继续命中,这样接下来的语句都会重新执行而不继续check cache。我在Dockerfile中加入了一行“MAINTAINER Jeorch”,Step-2还会使用cache,而接下来的都不会使用cache。

▶ docker build -t="jeorch/ddsaas:1.0.1" ./
Sending build context to Docker daemon  266.2kB
Step 1/9 : FROM golang:alpine
 ---> 20ff4d6283c0
Step 2/9 : RUN apk add --no-cache git mercurial
 ---> Using cache
 ---> 7c76541453d4
Step 3/9 : MAINTAINER Jeorch
 ---> Running in 33bbfbd73508
Removing intermediate container 33bbfbd73508
 ---> ac2188cd26c4
Step 4/9 : RUN go get github.com/alfredyang1986/blackmirror
 ---> Running in 3363c4394984
Removing intermediate container 3363c4394984
 ---> db9237361148
Step 5/9 : RUN go get github.com/alfredyang1986/ddsaas
 ---> Running in 738534a17f5e
Removing intermediate container 738534a17f5e
 ---> fe40c81e076d
Step 6/9 : ADD deploy-config/ /go/bin/
 ---> ddad378cdf99
Step 7/9 : RUN go install -v github.com/alfredyang1986/ddsaas
 ---> Running in 74d83f8a7c9a
Removing intermediate container 74d83f8a7c9a
 ---> 50f17bf6530e
Step 8/9 : WORKDIR /go/bin
 ---> Running in a904feb924d2
Removing intermediate container a904feb924d2
 ---> f1297882f28d
Step 9/9 : ENTRYPOINT ["ddsaas"]
 ---> Running in 3dda764560b3
Removing intermediate container 3dda764560b3
 ---> 236b15602a89
Successfully built 236b15602a89
Successfully tagged jeorch/ddsaas:1.0.1

LABEL比MAINTAINER更灵活,推荐使用LABEL,弃用MAINTAINER。详情看深入Dockerfile(一): 语法指南

2. build Dockerfile 不使用cache

Dockerfile需要全部重新build,即我们不需要利用cache,我们可以在docker build 命令后使用–no-cache。

▶ docker build -t="jeorch/ddsaas:1.0.1" ./ --no-cache
Sending build context to Docker daemon  266.2kB
Step 1/8 : FROM golang:alpine
 ---> 20ff4d6283c0
Step 2/8 : RUN apk add --no-cache git mercurial
 ---> Running in 770bcf003ff2
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
(1/16) Installing nghttp2-libs (1.32.0-r0)
(2/16) Installing libssh2 (1.8.0-r3)
(3/16) Installing libcurl (7.61.1-r1)
(4/16) Installing expat (2.2.5-r0)
(5/16) Installing pcre2 (10.31-r0)
(6/16) Installing git (2.18.1-r0)
(7/16) Installing libbz2 (1.0.6-r6)
(8/16) Installing libffi (3.2.1-r4)
(9/16) Installing gdbm (1.13-r1)
(10/16) Installing ncurses-terminfo-base (6.1_p20180818-r1)
(11/16) Installing ncurses-terminfo (6.1_p20180818-r1)
(12/16) Installing ncurses-libs (6.1_p20180818-r1)
(13/16) Installing readline (7.0.003-r0)
(14/16) Installing sqlite-libs (3.24.0-r0)
(15/16) Installing python2 (2.7.15-r1)
(16/16) Installing mercurial (4.6.1-r0)
Executing busybox-1.28.4-r0.trigger
OK: 80 MiB in 30 packages
Removing intermediate container 770bcf003ff2
 ---> 86dfeb5c30c2
Step 3/8 : RUN go get github.com/alfredyang1986/blackmirror
 ---> Running in d7dd1c8fab79
Removing intermediate container d7dd1c8fab79
 ---> c7b61e4b6722
Step 4/8 : RUN go get github.com/alfredyang1986/ddsaas
 ---> Running in c783e5fe874c
Removing intermediate container c783e5fe874c
 ---> c07eda8eb619
Step 5/8 : ADD deploy-config/ /go/bin/
 ---> aa51cfe6311f
Step 6/8 : RUN go install -v github.com/alfredyang1986/ddsaas
 ---> Running in 6ca73a6969df
Removing intermediate container 6ca73a6969df
 ---> be7090e0095e
Step 7/8 : WORKDIR /go/bin
 ---> Running in 9f19f951d662
Removing intermediate container 9f19f951d662
 ---> a0894151c5e6
Step 8/8 : ENTRYPOINT ["ddsaas"]
 ---> Running in 9404dad6e3bf
Removing intermediate container 9404dad6e3bf
 ---> 2681d9a56d7b
Successfully built 2681d9a56d7b
Successfully tagged jeorch/ddsaas:1.0.1

3. build Dockerfile 全部利用cache

正常执行docker build就行。

参考

<think>嗯,用户想了解DockerBuildxBuildDockerBuild的区别及使用场景。看来用户正在学习Docker的高级功能,可能是个开发或运维工程师,正在评估是否需要迁移到Buildx。从引用材料来看,用户已经做了些功课,但需要系统性的对比。用户特别强调“功能对比和主要区别”,说明ta需要决策依据。可能实际遇到了多平台构建或缓存优化的问题,只是没明说。核心区别其实在三个方面:架构层面(BuildKit)、功能广度、多平台支持。普通dockerbuild本质是单点单平台构建工具,而Buildx是分布式构建框架。尤其值得注意的是,用户提供的引用[4]明确提到“默认dockerbuild无法跨平台构建”,这点必须重点强调。缓存机制差异也值得展开。用户引用的[2]提到“缓存回退”,说明ta可能关心构建速度。Buildx支持的缓存导出/导入(尤其是registry缓存)对CI/CD流水线很实用,普通build的缓存只能本地复用。多平台场景要特别说明用户引用的案例(引用[4]的跨平台二进制安装)。用户给出的命令示例里有--platform参数和--push,说明ta可能需要发布多架构镜像,这时候Buildx几乎是唯一选择。对了,用户提到“使用场景”对比,可以补充一个典型场景表:本地开发调试用dockerbuild就够了,但生产环境多平台交付必须用Buildx。还有当需要并行构建或高级缓存时,即使用户不需要多平台,Buildx也有优势。最后那个构建参数表格很必要,用户给出的命令示例里出现了--push这种Buildx特有参数。需要强调--output这类参数改变了Docker构建的固有模式,比如可以直接输出镜像文件而不是推送到仓库。</think> 以下是 **Docker Buildx Build** 与 **Docker Build** 的核心区别及使用场景分析,结合引用内容整理: --- ### 一、功能对比 | **特性** | **Docker Build** | **Docker Buildx Build** | |------------------------|--------------------------------------|----------------------------------------| | **构建引擎** | 传统 Builder(默认) | **BuildKit**(高性能引擎,支持并行构建)[^2][^4] | | **多平台支持** | ❌ 仅支持当前平台 | ✅ 支持 `--platform`(同时构建 AMD/ARM 等)[^2][^4] | | **缓存机制** | 基础层缓存 | 高级缓存(支持缓存回退、远程缓存)[^2] | | **构建输出格式** | 镜像文件 | 镜像、OCI 归档、Dockerfile、Registry推送等[^2][^5] | | **分布式构建** | ❌ 单点构建 | ✅ 支持多节点并行构建[^4] | | **跨平台编译** | ❌ 需手动模拟平台 | ✅ 原生支持(无需 QEMU 配置)[^4] | | **典型场景** | 本地开发、单平台测试 | CI/CD、多平台部署、生产环境镜像分发 | --- ### 二、核心区别 1. **构建引擎不同** - `docker build`:使用传统构建器,功能有限。 - `docker buildx build`:集成 **BuildKit**(需启用 `DOCKER_BUILDKIT=1`),提供更快的构建速度、增量缓存优化和高级特性[^2][^4]。 2. **多架构构建能力** - `docker build` 只能构建当前主机架构的镜像(如 x86)。 - `buildx` 通过 `--platform linux/amd64,linux/arm64` 参数一键生成多平台镜像,无需多台设备[^2][^4]。 3. **输出与缓存策略** - `buildx` 支持推送镜像到仓库(`--push`)、导出缓存到远程(`--cache-to`)、复用缓存(`--cache-from`),显著提升流水线效率[^2][^5]。 - 传统 `build` 仅支持本地缓存。 4. **扩展性与部署** - `buildx` 可创建多个 **构建器实例**(如 `docker buildx create --name mybuilder`),支持远程节点和云构建[^4]。 - `docker build` 仅限本地构建环境。 --- ### 三、典型使用场景 #### ✅ **优先用 `docker build`:** - 本地调试、快速验证镜像功能。 - 仅需为单一架构构建镜像。 #### ✅ **必须用 `docker buildx build`:** 1. **多平台发布**(如同时支持 Intel/Apple Silicon) ```bash docker buildx build --platform linux/amd64,linux/arm64 -t myapp:v1 --push . ``` 2. **CI/CD 流水线优化** ```bash # 导出缓存到仓库,供后续构建复用 docker buildx build --cache-to type=registry,ref=mycache:v1 \ --cache-from type=registry,ref=mycache:v1 . ``` 3. **复杂输出管理** ```bash # 直接输出 Dockerfile 或 OCI 包而非镜像 docker buildx build --output type=docker,dest=./app.tar . ``` --- ### 四、总结 - **`docker build`**:简单场景下的轻量级工具。 - **`docker buildx build`**:面向生产环境和DevOps工作流的**进阶解决方案**,尤其适合多平台分发、高性能构建和复杂缓存需求[^2][^4][^5]。 > 💡 **操作建议**:启用 BuildKit 后优先使用 `buildx`(Docker Desktop 默认内置),传统命令将逐步淘汰[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值