Docker用BuildKit实现依赖缓存

我们在持续构建中,经常遇到编译或者运行需要安装大量依赖。像php,java,go,nodejs,python等等。似乎现在没个包管理的语言都不敢出来推广。

但是在使用多阶段构建后,经常遇到依赖反复安装导致构建时间变成的事情。

后面发现了BuildKit可以完成这个事情。

比如下面一个基于nodejs前端工程化的例子:

npm安装依赖后,执行npm run build,将build生成的dist目录下的文件复制到nginx容器提供服务。

而–mount 可以挂载一个具名的缓存来缓存依赖目录,build的时候同样挂载进去即可。下次构建的时候挂载同样的缓存,就不用重复安装了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# syntax = docker/dockerfile:experimental
FROM node:10-alipine3.9 as builder
WORKDIR /code
COPY . .
RUN --mount=type=cache,target=/code/node_modules,id=my_app_npm_module,sharing=locked --mount=type=cache,target=/root/.npm,id=npm_cache npm install --registry=https://registry.npm.taobao.org
RUN --mount=type=cache,target=/code/node_modules,id=my_app_npm_module,sharing=locked npm run build
FROM nginx:1.19.2-alpine
RUN echo $'server {\n\
listen 80;\n\
listen [::]:80;\n\
server_name localhost;\n\
location / {\n\
root /usr/share/nginx/html;\n\
try_files $uri $uri /index.html;\n\
}\n\
}' > /etc/nginx/conf.d/default.conf
COPY --from=builder /code/dist /usr/share/nginx/html

注意事项

  • 版本大于18.06
  • 临时启用设置环境变量为 DOCKER_BUILDKIT=1DOCKER_BUILDKIT=1 docker build .
  • 永久性启用 vi /etc/docker/daemon.json
    1
    { "features": { "buildkit": true } }
  • docker-compose 设置环境变量 COMPOSE_DOCKER_CLI_BUILD=1

参考资料

关注公众号 尹安灿