DockerDocker容器

如何优化CI中不断优化docker build速度

2021-08-05  本文已影响0人  柚子net

当我们在完全使用gitlab runner,或者其他工具,借助完整的Dockerfile完成项目镜像制作中时,大大提高了我们的运维发布效率,但是越来越长的docker build时间也成为快速发布上线的障碍了,我们就来总结一下有哪些优化docker build的方法。

1. 充分利用docker build镜像分层缓存策略

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代码进来,如此一来
# 当依赖未变化时,就不需要重复运行以来安装过程了。
COPY ./ ./

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

2. 使用多阶段构建镜像

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
# 关键步骤,我们从上一阶段的 node镜像中,copy出我们需要的最终编译好的前端静态文件
# 放置到nginx镜像中即可,最终景象将只包含nginx以及静态文件
COPY --from=builder /data/dist /usr/share/nginx/html
RUN chown -R nginx:nginx /usr/share/nginx/html/

EXPOSE 80

3. 使用docker buildkit在build阶段挂载缓存

{
  "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了。

上一篇 下一篇

猜你喜欢

热点阅读