# Dockerfile改动一行代码,Jenkins编译速度提升了将近80倍
如上一篇文章所讲的,因为磁盘空间不足的问题,仔细学习了一下docker build cache
相关的内容,学习到
- Docker 构建过程是将 Dockerfile 中的指令转化为一个个构建层(Build Layer)。每一个指令都会生成一个构建层,而所有构建层组合在一起,形成一个完整的镜像。构建过程中的每一步都是无状态的,意味着在同一主机上,对相同的 Dockerfile 执行相同的指令应该得到相同的结果。
- 通过
.dockerignore
文件排除掉日志,编译类库文件等。保证文件的一致性,可以提高缓存构建层的复用
发现项目的Dockerfile文件有待改造的地方。通过对项目的简单两部操作,将代码编译速度提升了将近80倍。具体步骤如下:
# 1. 优化Dockerfile文件
# 原Dockerfile文件
# 编译基础镜像为golang:alpine
FROM golang:alpine AS builder
# 标记当前阶段为编译阶段
LABEL stage=gobuilder
# 修改Alpine Linux的软件包源为阿里云镜像源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 更新软件包索引并安装tzdata时区数据包和upx工具
RUN apk update --no-cache && apk add --no-cache tzdata && apk add --no-cache upx
# 指定工作目录
WORKDIR /builder
# 禁用CGO
ENV CGO_ENABLED=0
# 设置公司golang代理服务
ENV GOPROXY=http://goproxy.office.xxxxxx.com,direct
# 忽略私有包的sum验签
ENV GONOSUMDB=goproxy.office.xxxxxx.com/*
# 赋值当前项目所有文件到容器工作目录
COPY . .
# 编译项目可执行文件,并压缩生成的二进制文件
RUN go build -ldflags="-s -w" -tags=jsoniter -o api/bin/main api/main.go \
&& upx -q -9 /builder/api/bin/main
# 容器运行镜像为alpine
FROM alpine
# 标记当前阶段为运行阶段
LABEL stage=gorunner
# 参数指定配置文件名称
ARG config_file
# 从builder同步时区
COPY /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ=Asia/Shanghai
# 新建日志目录
# RUN mkdir /data/applogs && mkdir /data/weblogs
# 指定工作目录
WORKDIR /app
# 从编译容器复制运行二进制文件和配置信息
COPY /builder/api/bin/main /app/main
COPY /builder/api/etc/${config_file} /app/api.yaml
# 运行服务
CMD ["./main", "-f", "api.yaml"]
在上面的Dockerfile RUN go build ....
这条命令前增加一个命令RUN go mod download
生成golang 模块下载的构建层。这样不用每一次去构建模块了。
# 修改后Dockerfile文件
# 编译基础镜像为golang:alpine
FROM golang:alpine AS builder
# 标记当前阶段为编译阶段
LABEL stage=gobuilder
# 修改Alpine Linux的软件包源为阿里云镜像源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 更新软件包索引并安装tzdata时区数据包和upx工具
RUN apk update --no-cache && apk add --no-cache tzdata && apk add --no-cache upx
# 指定工作目录
WORKDIR /builder
# 禁用CGO
ENV CGO_ENABLED=0
# 设置公司golang代理服务
ENV GOPROXY=http://goproxy.office.xxxxxx.com,direct
# 忽略私有包的sum验签
ENV GONOSUMDB=goproxy.office.xxxxxx.com/*
# 赋值当前项目所有文件到容器工作目录
COPY . .
# 下载go依赖模块
RUN go mod download
# 编译项目可执行文件,并压缩生成的二进制文件
RUN go build -ldflags="-s -w" -tags=jsoniter -o api/bin/main api/main.go \
&& upx -q -9 /builder/api/bin/main
# 容器运行镜像为alpine
FROM alpine
# 标记当前阶段为运行阶段
LABEL stage=gorunner
# 参数指定配置文件名称
ARG config_file
# 从builder同步时区
COPY /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ=Asia/Shanghai
# 新建日志目录
# RUN mkdir /data/applogs && mkdir /data/weblogs
# 指定工作目录
WORKDIR /app
# 从编译容器复制运行二进制文件和配置信息
COPY /builder/api/bin/main /app/main
COPY /builder/api/etc/${config_file} /app/api.yaml
# 运行服务
CMD ["./main", "-f", "api.yaml"]
# 2. 新增.dockerignore
文件排除掉日志,编译类库文件
排除掉相关文件的copy
操作。
# Ignore development and editor-related files
.DS_Store
# Ignore version control directories
.git/
# Exclude specific directories and their contents
tmp/