如何優(yōu)化CI中不斷優(yōu)化docker build速度

當(dāng)我們?cè)谕耆褂胓itlab runner,或者其他工具,借助完整的Dockerfile完成項(xiàng)目鏡像制作中時(shí),大大提高了我們的運(yùn)維發(fā)布效率,但是越來越長(zhǎng)的docker build時(shí)間也成為快速發(fā)布上線的障礙了,我們就來總結(jié)一下有哪些優(yōu)化docker build的方法。

1. 充分利用docker build鏡像分層緩存策略

  • 這也是我們最常用的第一種加速構(gòu)建鏡像的方式,以nodejs項(xiàng)目為例:
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項(xiàng)目的pom.xml等
COPY package.json ./
COPY yarn.lock ./
COPY .yarnrc ./

RUN yarn --no-cache

# 在完成依賴安裝后,我們?cè)赾opy代碼進(jìn)來,如此一來
# 當(dāng)依賴未變化時(shí),就不需要重復(fù)運(yùn)行以來安裝過程了。
COPY ./ ./

EXPOSE 8080
ENTRYPOINT [ "/entrypoint.sh" ]
CMD ["yarn", "start"]

2. 使用多階段構(gòu)建鏡像

  • 以react前端項(xiàng)目為例
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階段掛載緩存

  • 這是本文的重點(diǎn),做了很多的CI項(xiàng)目中后,大家都在思考,如果在docker build階段,能夠掛在上volume來做緩存,那該多好呀,那么,現(xiàn)在,他來了
    在 docker 18.09以上版本,有一個(gè)Experimental特性, buildkit工具,默認(rèn)是沒有打開的,我們可以通過 export DOCKER_BUILDKIT=1 之后在進(jìn)行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

我們掛在了一個(gè)id為yarn_cache的卷到 yarn cache dir下,那么每次安裝的依賴本地緩存文件接回寫入到緩存中,并在docker build完成之后從運(yùn)行時(shí)中卸載并保存,下載我們就有機(jī)會(huì)體驗(yàn)擁有本地緩存的完美docker build了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 想要改進(jìn)這個(gè)備忘單嗎?參見[貢獻(xiàn)](#貢獻(xiàn))部分! 目錄 [為何選擇Docker](#why-docker) [先...
    iOSDevLog閱讀 2,221評(píng)論 0 3
  • 實(shí)例來源:tofar 摘錄來源:Docker — 從入門到實(shí)踐 歡迎大家添加自己的實(shí)例 (email: yun_...
    molscar閱讀 497評(píng)論 1 1
  • 原文地址:https://github.com/KeKe-Li/docker-directive docker 存...
    萌面菠蘿閱讀 569評(píng)論 0 0
  • 本章內(nèi)容 ◆ Docker簡(jiǎn)介◆ Docker 鏡像與制作◆ Docker 數(shù)據(jù)管理◆ Docker 網(wǎng)絡(luò)◆ Do...
    Liang_JC閱讀 918評(píng)論 0 0
  • 前言 當(dāng)我們需要使用某個(gè)容器的時(shí)候,通常先從docker hub或其它源上下載對(duì)應(yīng)的鏡像,然后通過一條命令就可以將...
    wanzhouyi閱讀 223評(píng)論 0 1

友情鏈接更多精彩內(nèi)容