关键在于让变化少的指令靠前、变化多的靠后,这样缓存链才不容易断裂;Docker逐层比对哈希值,某层变更则后续全重构建,因此需将稳定指令(如FROM、依赖安装)前置,用固定镜像标签、合并RUN命令、避免非确定性操作,并通过多阶段构建隔离编译与运行环境,辅以.dockerignore精简上下文。

关键在于让变化少的指令靠前、变化多的靠后,这样缓存链才不容易断裂。Docker 构建时逐层比对哈希值,一旦某层变了,后面全得重来。
把基础和依赖放最前面
FROM 镜像、系统包安装这些几乎不随业务改动,理应最先执行。用固定标签(比如 node:20.15-slim 而不是 node:latest),避免上游更新意外破坏整个缓存链。
- 合并 apt 更新、安装、清理为一条 RUN: RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
- 避免在 RUN 中调用 date、curl 外部接口等带不确定性输出的命令,它们每次生成不同哈希
- 用 COPY 替代 ADD,除非真需要自动解压 tar 包;ADD 行为更隐晦,容易干扰缓存判断
依赖文件先于源码复制
package.json、requirements.txt、go.mod 这类文件比代码本身稳定得多。先复制它们、安装依赖,再复制源码,能确保改代码不触发重装依赖。
MiniMax 图片理解 + 网络搜索 MCP 工具。适配 Docker 环境(极空间等),支持图片 OCR 识别、图像内容理解、网络搜索。API Key 安全存储在本地 credentials 文件,不暴露在代码中。
- Node.js:COPY package*.json ./ → RUN npm ci --only=production → COPY . .
- Python:COPY requirements.txt . → RUN pip install --no-cache-dir -r requirements.txt → COPY . .
- Go:COPY go.mod go.sum . → RUN go mod download → COPY . .
用多阶段构建隔离编译与运行
编译工具链、测试依赖、中间产物都不该进最终镜像。第一阶段负责构建,第二阶段只拿成品二进制或静态资源,天然切断开发期文件对运行层缓存的影响。
- 例如 Go 项目:第一阶段用 golang:1.22-alpine 编译,第二阶段用 alpine:3.20 只 COPY 可执行文件
- Node.js 构建型项目:build 阶段用完整环境跑 npm run build,最后阶段用 nginx:alpine 或 node:20-slim 托管 dist 目录
精简上下文,配合 .dockerignore
构建上下文传得越少,COPY 指令越不容易因无关文件变动而失效。.dockerignore 不是可选项,而是必选项。
- 务必排除:node_modules/、.git/、**/*.log、tmp/、.DS_Store
- 如果项目里有大体积静态资源(如 videos/、datasets/),也建议单独管理,不纳入构建上下文
- WORKDIR 要显式声明,避免路径叠加导致 COPY 行为不可预期

















