當(dāng)我們在完全使用gitlab runner敞贡,或者其他工具,借助完整的Dockerfile完成項目鏡像制作中時摄职,大大提高了我們的運維發(fā)布效率誊役,但是越來越長的docker build時間也成為快速發(fā)布上線的障礙了获列,我們就來總結(jié)一下有哪些優(yōu)化docker build的方法。
1. 充分利用docker build鏡像分層緩存策略
- 這也是我們最常用的第一種加速構(gòu)建鏡像的方式蛔垢,以nodejs項目為例:
FROM node:12.18-alpine
LABEL maintainer="xxx<xx@xxx.com>"
# 安裝常用工具鏈
RUN \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache \
bash \
vim \
make \
tzdata \
git python make gcc g++ && \
cp -r -f /usr/share/zoneinfo/Hongkong /etc/localtime
ENV NODE_ENV=production
WORKDIR /data/
# 先拷貝文件變化需要安裝依賴的文件击孩,例如nodejs的package.json,java項目的pom.xml等
COPY package.json ./
COPY yarn.lock ./
COPY .yarnrc ./
RUN yarn --no-cache
# 在完成依賴安裝后,我們在copy代碼進來鹏漆,如此一來
# 當(dāng)依賴未變化時巩梢,就不需要重復(fù)運行以來安裝過程了。
COPY ./ ./
EXPOSE 8080
ENTRYPOINT [ "/entrypoint.sh" ]
CMD ["yarn", "start"]
2. 使用多階段構(gòu)建鏡像
- 以react前端項目為例
FROM node:12.16-alpine as builder
LABEL maintainer="xxx<xx@xxx.com>"
RUN \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add git python make gcc g++
ENV NODE_ENV development
WORKDIR /data/
COPY package.json ./
COPY .yarnrc ./
COPY yarn.lock ./
RUN yarn install --silent --no-cache
COPY ./ ./
RUN NODE_ENV=production yarn build
FROM nginx:1.20.1-alpine
LABEL maintainer="xxx<xx@xxx.com>"
RUN \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf
# 關(guān)鍵步驟艺玲,我們從上一階段的 node鏡像中且改,copy出我們需要的最終編譯好的前端靜態(tài)文件
# 放置到nginx鏡像中即可,最終景象將只包含nginx以及靜態(tài)文件
COPY --from=builder /data/dist /usr/share/nginx/html
RUN chown -R nginx:nginx /usr/share/nginx/html/
EXPOSE 80
3. 使用docker buildkit在build階段掛載緩存
- 這是本文的重點板驳,做了很多的CI項目中后,大家都在思考碍拆,如果在
docker build
階段若治,能夠掛在上volume來做緩存,那該多好呀感混,那么端幼,現(xiàn)在,他來了
在 docker 18.09以上版本弧满,有一個Experimental特性婆跑, buildkit工具,默認是沒有打開的庭呜,我們可以通過export DOCKER_BUILDKIT=1
之后在進行docker build滑进,或者在/etc/docker/daemon.json
中配置開啟:
{
"log-driver": "json-file",
"exec-opts": ["native.cgroupdriver=systemd"],
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"features": { "buildkit": true }
}
開啟之后我們就可以修改上面的Dockerfile,來完成一次速度的飛躍:
# syntax=docker/dockerfile:1.3
FROM node:12.16-alpine as builder
LABEL maintainer="xxx<xx@xxx.com>"
RUN \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add git python make gcc g++
ENV NODE_ENV development
WORKDIR /data/
COPY package.json ./
COPY .yarnrc ./
COPY yarn.lock ./
RUN yarn install --silent --no-cache
COPY ./ ./
# 需要開啟docker Experimental特性支持募谎,docker version > 18.09 , export DOCKER_BUILDKIT=1
RUN --mount=type=cache,id=yarn_cache,sharing=shared,target=/usr/local/share/.cache \
NODE_ENV=production yarn build
FROM nginx:1.20.1-alpine
LABEL maintainer="xxx<xx@xxx.com>"
RUN \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /data/dist /usr/share/nginx/html
RUN chown -R nginx:nginx /usr/share/nginx/html/
EXPOSE 80
我們掛在了一個id為yarn_cache的卷到 yarn cache dir
下扶关,那么每次安裝的依賴本地緩存文件接回寫入到緩存中,并在docker build完成之后從運行時中卸載并保存数冬,下載我們就有機會體驗擁有本地緩存的完美docker build了节槐。
- 更多內(nèi)容我們可以去翻閱官方的docker buildkit相關(guān)文檔了
https://docs.docker.com/develop/develop-images/build_enhancements/
https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md
目前以上就是簡單介紹我目前使用到的所有優(yōu)化方案了,歡迎小伙伴們來補充拐纱。