docker build 是干什么的
docker build 按 Dockerfile 的指令逐层构建镜像:每条指令生成一层,能命中缓存的层直接复用,因此调整指令顺序就能显著改变构建速度。构建时会把上下文目录整体传给构建引擎,上下文越大越慢,所以排除无关文件和管理好缓存是日常构建效率的两条主线。
基本信息
| 基本语法 | docker build -t 名称:版本 上下文目录 |
|---|---|
| 上下文 | 目录、地址或代码仓库地址;用忽略文件排除无关内容 |
| 常用参数 | -f 指定 Dockerfile、--build-arg 传参、--target 指定阶段、--no-cache 禁用缓存 |
| 产物 | 构建成功得到本地镜像,可直接运行或推送到仓库 |
| 缓存命中 | 某条指令的输入未变化时可复用已有层,改动越靠前失效范围越大 |
| 多架构 | 配合构建工具可产出多平台镜像,供不同架构机器拉取 |
典型使用场景
- 打包自研应用:把代码或编译产物与运行时环境一起固化成镜像
- 制作基础镜像:统一团队的操作系统、时区、语言运行时与常用工具
- 流水线构建:在流水线里构建并推送镜像,再由部署过程拉取
- 复用构建缓存:把不常变的依赖安装指令放前面,缩短迭代等待
- 多阶段产物提取:只构建到某个阶段,用于验证编译结果
- 本地复现构建问题:在打包环境之外重现依赖缺失或权限问题
构建慢的常见原因
| 现象 | 原因 | 处理方式 |
|---|---|---|
| 上下文传输很久 | 目录里混入依赖、版本库与压缩包 | 补全忽略文件,把无关内容排除 |
| 每次都重新装依赖 | 依赖文件与源码一起复制,源码一变缓存全失效 | 先复制依赖清单并安装,再复制源码 |
| 全量重构建 | 习惯性禁用缓存 | 只在依赖异常时才禁用缓存 |
| 镜像体积大 | 构建工具链与运行产物混在同一阶段 | 改用多阶段构建,只拷贝运行产物 |
| 推送耗时 | 镜像层数多、体积大 | 合并指令并精简依赖,减少层数与体积 |
构建示例
构建示例
docker build -t myapp:1.0.0 . # 基础构建
docker build -f docker/Dockerfile.prod -t myapp:prod . # 指定 Dockerfile
docker build --target builder -t myapp:builder . # 只构建到某阶段
docker build --build-arg VERSION=1.0.0 -t myapp:1.0.0 . # 传入构建参数
docker history myapp:1.0.0 # 看每层大小,定位臃肿层构建上下文不要包含依赖目录、版本库与压缩包:它们会被整体传给构建引擎,既浪费时间也容易把密钥与内部信息带进镜像。
指令顺序决定缓存命中率:把最稳定的步骤放前面、最常变动的放后面,日常改代码的构建就会快一个数量级。
构建参数会写进镜像历史:敏感值不要用构建参数传递,需要密钥时在运行时注入或使用密钥挂载。
构建缓存会持续占用宿主磁盘:长期构建的机器要定期清理无用镜像与构建缓存,否则磁盘先于业务出问题。
流水线里的构建实践
- 把依赖安装与源码复制分成两步,缩短日常构建等待时间
- 为镜像打上提交标识标签,便于定位某次发布对应的代码
- 构建产物做基础校验,避免把空目录或错误文件打进镜像
- 在流水线里缓存依赖下载结果,减少重复下载开销
- 定期清理构建缓存与无用镜像,控制构建机磁盘水位