Docker 镜像瘦身和构建缓存:让发布更快也更可控
一、镜像大不是小问题
Docker 镜像过大带来的不是磁盘浪费这么简单。它会拉长 CI 构建时间、占用镜像仓库存储、拖慢节点拉取速度,还会扩大漏洞扫描范围。国内很多团队的发布慢,表面看是流水线慢,实际是基础镜像随意、依赖层不稳定、构建缓存用不上。
镜像瘦身的原则很直接:运行时只带运行需要的文件,构建工具留在 build stage;依赖层尽量稳定,业务代码层放后面;不要把 .git、日志、测试数据、临时文件打进镜像。瘦身不是越小越好,调试能力、安全更新和构建速度也要一起考虑。
| 做法 | 收益 | 注意点 |
|---|---|---|
| 多阶段构建 | 减少运行时文件 | stage 边界要清晰 |
| 固定基础镜像版本 | 构建可复现 | 定期安全升级 |
.dockerignore | 减少上下文 | 不要误排除必要文件 |
| BuildKit 缓存 | 加速依赖安装 | CI 需要配置缓存导出 |
二、以 Go 服务为例做多阶段构建
下面的 Dockerfile 把编译和运行分开。编译阶段使用 Go 镜像,运行阶段使用 Debian slim,并只复制二进制文件和证书。对于需要访问 HTTPS 的服务,证书包不能忘。
# syntax=docker/dockerfile:1.7
FROM golang:1.22-bookworm AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/app ./cmd/api
FROM debian:12-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates tzdata \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /out/app /app/app
USER 65532:65532
EXPOSE 8080
ENTRYPOINT ["/app/app"]
构建时启用 BuildKit,可以复用 Go module 和编译缓存。CI 环境里如果每次都是全新机器,还要把缓存导出到 registry 或 CI 缓存系统,否则本地快、流水线仍然慢。
export DOCKER_BUILDKIT=1
docker build -t registry.example.com/order-api:2026.07.07 .
docker image ls registry.example.com/order-api
docker run --rm -p 8080:8080 registry.example.com/order-api:2026.07.07
三、构建上下文经常被忽略
docker build . 会把当前目录作为上下文发送给 Docker daemon。项目里如果有 node_modules、测试报告、临时压缩包、历史日志,都会影响构建速度,甚至被误复制进镜像。.dockerignore 应该像 .gitignore 一样维护。
.git
.github
node_modules
dist
coverage
*.log
tmp
.env
Dockerfile*
docker-compose*.yml
不要把 .env 打进镜像。环境变量、数据库密码、Token 应该由运行环境注入,例如 Kubernetes Secret、Docker Compose env_file 或云厂商密钥服务。镜像应该是同一个制品在不同环境运行,而不是为测试、预发、生产分别构建三份带不同配置的镜像。
四、安全扫描要接入发布流程
镜像瘦身和安全扫描要一起做。基础镜像越大,漏洞列表通常越长,但更小的镜像也不代表一定安全。关键是固定版本、定期重建、扫描高危漏洞,并确认漏洞是否影响实际运行路径。
# 示例:使用 trivy 扫描镜像
trivy image --severity HIGH,CRITICAL registry.example.com/order-api:2026.07.07
# 查看镜像层
docker history registry.example.com/order-api:2026.07.07
# 检查容器内用户
docker run --rm registry.example.com/order-api:2026.07.07 id
实践建议:先从发布最频繁的 3 个服务开始治理 Dockerfile,把多阶段构建、.dockerignore、非 root 用户、固定基础镜像版本和漏洞扫描补齐。不要为了追求极限体积牺牲可维护性;对业务团队来说,稳定复现、构建速度和安全更新节奏,比单纯少几十 MB 更重要。
如果你正在学习云原生或搭建个人项目,推荐试试腾讯云轻量应用服务器,新用户专享优惠,一键部署开发环境非常方便:点击查看优惠
更多推荐
所有评论(0)