第26章|Docker 实战:开发环境、构建缓存、compose 与本地交付

这一章把 Docker 从「能跑」拉到「团队能一起跑」:Compose 把多服务编排成一条命令, 多阶段构建 让镜像又小又稳,BuildKit 与缓存挂载 让 CI 与本地构建不再互相折磨。 目标很简单:新人 docker compose up 就能开工,且行为与生产足够接近。

Compose

一条命令拉起整套栈

  • services / networks / volumes 三位一体
  • depends_on + healthcheck 控制启动顺序
  • override 文件区分 dev 与 CI
Build

缓存是生产力

  • 多阶段:builder 与 runtime 分离
  • BuildKit cache mount 加速依赖安装
  • .dockerignore 缩小构建上下文
Delivery

本地交付 = 可复现契约

  • 环境变量与机密分层(.env.example)
  • bind mount 热重载 vs 纯容器运行
  • 与生产镜像 target 对齐(dev/prod)

1. Docker Compose:把「一堆容器」变成「一个产品」

单容器适合 demo;真实项目几乎总有 Web、数据库、缓存、队列。Compose 的价值是:用声明式 YAML 描述谁连谁、数据放哪、谁先起, 而不是每人手写一长串 docker run

1.1 核心概念

常见坑:depends_on 只保证启动顺序,不保证依赖服务已可接受连接。生产级本地栈请给 DB 配 healthcheck,应用侧用重试或 wait 脚本。
Compose 拓扑:网络、卷、依赖 同一 bridge 网络内按服务名解析;数据卷与 bind mount 各司其职 network: app_net web bind mount: ./src port 8000:8000 depends_on: db, redis db volume: pg_data healthcheck TCP 5432 redis cache session DNS: db:5432
图 1:典型 Compose 栈。Web 通过服务名访问 db/redis;DB 用命名卷持久化;开发时 Web 可 bind mount 源码实现热重载。

2. 多阶段构建:builder 胖、runtime 瘦

第一阶段装编译器、跑测试、打静态资源;最终镜像只拷贝产物与运行时依赖。这样攻击面小、拉取快、部署省带宽。 在 Dockerfile 里用 AS builder / FROM ... AS runtime,Compose 里可用 target: 只构建 dev stage 做本地调试。

多阶段构建:从「构建环境」到「运行镜像」 左侧 builder 可含 gcc/node_modules;右侧 final 仅 runtime + 产物 stage: builder FROM node:20 AS builder RUN npm ci && npm run build artifacts: dist/ devDependencies 不进入 final ~400MB+ layers (example) COPY --from stage: runtime FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html no compiler · minimal attack surface ~50MB class image (typical)
图 2:多阶段构建。构建阶段可任意臃肿;运行镜像只保留必要文件,体积与风险面同步下降。

3. 构建缓存与 BuildKit:让「改一行代码」别重装全世界

经典优化:先 COPY package.json package-lock.jsonRUN npm ci,后 COPY . .,这样改业务代码不会 bust 依赖层。 开启 BuildKit 后可用 cache mount(如 pip/npm 缓存目录挂载到缓存卷),在 CI 无层缓存时仍能显著加速。

口诀:「依赖锁定文件先进镜像 → 装依赖 → 再拷源码」。违反顺序 = 每次构建都像第一次。

4. 本地交付契约:.env、override、与生产对齐

  1. 仓库根提供 .env.example(全英文 key + 中文注释可写在 README),列出必填变量。
  2. docker-compose.override.yml(gitignore)放个人机器差异;团队共享 compose.dev.yml
  3. 机密不进 Git:用 env_file 或运行时注入,与第 19 章「secret 与 config 分离」一致。
  4. 生产镜像与本地尽量同一 Dockerfile final stage,避免「本地能跑、线上另一套」。
本地交付闭环:clone → configure → up → dev loop 目标:新人 15 分钟内可提交第一个 PR 级别的本地验证 clone cp .env compose up dev Hot reload path bind mount → editor save → framework reload → same DB/redis as team optional: docker compose watch for sync iterate
图 3:本地交付闭环。配置一次环境变量后,compose 拉起全栈;bind mount 让开发循环留在宿主机编辑器里完成。

5. 最小清单(可直接当团队规范)

自检三问:
1) 新人是否只需 copy env + compose up?
2) 改一行业务代码会不会触发全量依赖安装?
3) 本地跑的镜像与生产 final stage 是否同源?
← 上一章:镜像仓库与供应链 下一章:Kubernetes 入门 1 →