Dockerfile构建优化项

一、使用较小的基础镜像,如alpine

vim Dockerfile

# syntax=docker/dockerfile:1
FROM golang:1.17-alpine
WORKDIR /opt/app
COPY . .
RUN go build -o example
CMD ["/opt/app/example"]

二、多阶段构建

多阶段构建的本质其实就是将镜像构建过程拆分成编译过程和运行过程。
第一个阶段对应编译的过程,负责生成可执行文件;第二个阶段对应运行过程,也就是拷贝第一阶段的二进制可执行文件,并为程序提供运行环境
示例如下:

vim Dockerfile

# syntax=docker/dockerfile:1
# Step 1: build golang binary
FROM golang:1.17 as builder
WORKDIR /opt/app
COPY . .
RUN go build -o example

# Step 2: copy binary from step1
FROM ubuntu:latest
WORKDIR /opt/app
COPY --from=builder /opt/app/example ./example
CMD ["/opt/app/example"]

三、使用其他更小的镜像作为第二阶段的运行镜像

由于 Alpine 镜像并没有 glibc,所以在编译可执行文件时需指定 CGO_ENABLED=0,禁用了 CGO,这样程序才能在 Alpine 镜像中运行。

# syntax=docker/dockerfile:1

# Step 1: build golang binary
FROM golang:1.17 as builder
WORKDIR /opt/app
COPY . .
RUN CGO_ENABLED=0 go build -o example

# Step 2: copy binary from step1
FROM alpine
WORKDIR /opt/app
COPY --from=builder /opt/app/example ./example
CMD ["/opt/app/example"]

四、极限压缩

只需要把第二个阶段的镜像替换为一个“空镜像”,这个空镜像称为 scratch 镜像

 # syntax=docker/dockerfile:1

# Step 1: build golang binary
FROM golang:1.17 as builder
WORKDIR /opt/app
COPY . .
RUN CGO_ENABLED=0 go build -o example

# Step 2: copy binary from step1
FROM scratch
WORKDIR /opt/app
COPY --from=builder /opt/app/example ./example
CMD ["/opt/app/example"]

五、使用构建缓存,加速构建速度

构建慢原因

在第一阶段的构建过程中,我们先是用 COPY . . 的方式拷贝了源码,又进行了编译,这会产生一个缺点,那就是如果只是源码变了,但依赖并没有变,Docker 将无法复用依赖的镜像层缓存。在实际构建过程中,你会发现 Docker 每次都会重新下载 Golang 依赖。

优化方式:

先复制依赖文件,再下载依赖,最后再复制源码进行编译。基于这种思路,我们可以将第一阶段的构建修改如下。


# Step 1: build golang binary
FROM golang:1.17 as builder
WORKDIR /opt/app
COPY go.* ./
RUN go mod download
COPY . .
RUN go build -o example

六、常用基础镜像

1、常用通用镜像

2、java语言常用专用镜像

3、解释型语言常用专用镜像

作者:于浩  创建时间:2024-04-29 15:42
最后编辑:于浩  更新时间:2025-06-10 18:08