362 字
2 分钟
Docker 多阶段构建:如何把镜像从 1GB 瘦身到 50MB
镜像太大的罪与罚
不管是部署速度,还是存储成本,大镜像都是万恶之源。
一个典型的 Go 或 Node.js 应用,源码可能只有几 MB,但打出来的镜像动不动就几百 MB。
为什么?因为你基于 node:16 或 golang:1.18 这种全功能基础镜像,里面包含了 GCC、Python、Git 等一堆你运行时根本不需要的工具。
错误的写法 (Single Stage)
FROM golang:1.18WORKDIR /appCOPY . .RUN go build -o myapp main.goCMD ["./myapp"]结果:镜像大小 800MB+。因为你把 Go 的编译器、标准库源码都带上了。
正确的写法 (Multi-Stage)
我们利用 多阶段构建 (Multi-Stage Builds)。 第一阶段:编译(用重型镜像)。 第二阶段:运行(用极简镜像)。
# 阶段一:构建者FROM golang:1.18-alpine AS builderWORKDIR /appCOPY . .RUN go build -o myapp main.go
# 阶段二:运行者FROM alpine:latestWORKDIR /root/# 只拷贝编译好的二进制文件!COPY --from=builder /app/myapp .CMD ["./myapp"]结果:镜像大小 15MB。 只剩下一个 Alpine Linux 和一个二进制文件。清清爽爽。
前端也一样
Node.js 项目:
- Stage 1:
npm install+npm run build(需要 Node 环境,很大)。 - Stage 2:
nginx:alpine。把 Stage 1 生成的dist/文件夹拷进去。
总结
如果你交付给运维的镜像超过 500MB,请请他喝杯奶茶道歉。
然后回去加上 FROM ... AS builder。
瘦身不仅仅是为了省空间,更是为了安全(攻击面更小)。
Docker 多阶段构建:如何把镜像从 1GB 瘦身到 50MB
https://www.oferry.com/posts/a45/