前言
之前使用dockerfile构建镜像时,都是使用单个dockerfile构建,把构建好的二进制或jar包导出重写打包为镜像,这样比较麻烦无法自动化, 从其他地方了解到可以使用多阶段构建,跟GitHub的Action类似,方便快捷。
1.使用
在Dockerfile的多阶段构建中,最终生成的镜像是以最后一个阶段的镜像为准的
每个阶段都是一个FROM,以FROM为标识多个阶段
# 第一阶段:编译
# 必须用AS定义一个自定义别名 在其他阶段要使用
FROM golang:1.18 AS builder
# 设置工作目录(创建并cd过去)
WORKDIR /app
# 从宿主机复制main.go到容器当前目录(/app/main.go)
COPY main.go .
# 执行编译命令
RUN go build -o myapp /app/main.go
# 第二阶段:生成最终镜像
FROM alpine:latest
# 设置工作目录(创建并cd过去)
WORKDIR /root/
# 从第一阶段复制文件到第二阶段中
# --from 指定把builder阶段中的/app/myapp文件复制到当前镜像当前目录中(/root/myapp)
COPY --from=builder /app/myapp .
# 启动命令
CMD ["./myapp"]
2.构建go镜像
1.简单的go单文件
package main
import (
"fmt"
)
func main() {
fmt.Println("我是多阶段构建出来的镜像")
}
2.dockerfile
# 第一阶段:编译
# 必须用AS定义一个自定义别名 在其他阶段要使用
FROM golang:1.20 AS builder
# 设置工作目录(创建并cd过去)
WORKDIR /apps
# 从宿主机复制main.go到容器当前目录(/apps/main.go)
COPY main.go .
# 设置 Go 环境变量 切换模块源为中国Go模块代理服务器
RUN go env -w GOPROXY=https://goproxy.cn,direct
# 在当前目录初始化创建main模块并自动解析下载依赖(构建完整模块 tidy完善go.mod)
RUN go mod init main && go mod tidy
# 执行编译命令 编译好的二进制是/apps/main
RUN go build -o /apps/main /apps/main.go
# 第二阶段:生成最终镜像
FROM alpine:latest
# 设置工作目录(创建并cd过去)
WORKDIR /root/
# 从第一阶段复制文件到第二阶段中
# --from 指定把builder阶段中的/app/myapp文件复制到当前镜像当前目录中(/root/main)
COPY --from=builder /apps/main .
# 设置时区为上海,并且创建全局访问的软链接
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' > /etc/timezone \
&& ln -s /root/main /usr/bin/main
# 设置编码
ENV LANG C.UTF-8
# 创建软链接 解决二进制无法执行问题 amd架构必须执行
# RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
# 运行golang程序的命令
CMD main
3.构建镜像
docker build -f dockerfile -t g1 .
打包出来的镜像只有9m,符合alpine
镜像大小
运行
docker run --rm -it g1