代码之家  ›  专栏  ›  技术社区  ›  Pavel Perevezencev

多级Docker构建的工件缓存

  •  0
  • Pavel Perevezencev  · 技术社区  · 6 年前

    我有这样的码头工人

    # build-home
    FROM node:10 AS build-home
    WORKDIR /usr/src/app
    COPY /home/package.json /home/yarn.lock /usr/src/app/
    RUN yarn install
    COPY ./home ./
    RUN yarn build
    
    # build-dashboard
    FROM node:10 AS build-dashboard
    WORKDIR /usr/src/app
    COPY /dashboard/package.json /dashboard/yarn.lock /usr/src/app/
    RUN yarn install
    COPY ./dashboard ./
    RUN yarn build
    
    # run
    FROM nginx
    EXPOSE 80
    COPY nginx.conf /etc/nginx/nginx.conf
    COPY --from=build-home /usr/src/app/dist /usr/share/nginx/html/home
    COPY --from=build-dashboard /usr/src/app/dist /usr/share/nginx/html/dashboard
    

    这里构建两个react应用程序,然后将构建的工件放入nginx。为了提高构建性能,我需要缓存 dist 文件夹 build-home build-dashboard 构建阶段。 为此我创建了一个 volume 在里面 docker-compose.yml

    ...
      web:
        container_name: web
        build:
          context: ./web
        volumes:
          - ./web-build-cache:/usr/src/app
        ports:
          - 80:80
        depends_on:
          - api
    

    我在这个阶段停了下来,因为我不明白怎么加 体积 创建者 docker-compose 第一个是 建造家园 阶段,添加后 体积 构建仪表板 . 也许我应该创建一个两个卷,并将每个卷附加到每个构建阶段,但是如何做到这一点呢?

    更新:

    Initial build.

    家庭应用程序:

    1. 安装模块:100.91S
    2. 构建应用程序:39.51s

    仪表板应用程序:

    1. 安装模块:100.91S
    2. 构建应用程序:50.38s

    总时间:

    real    8m14.322s
    user    0m0.560s
    sys     0m0.373s
    

    Second build (无代码或依赖项更改):

    家庭应用程序:

    1. 安装模块:使用缓存
    2. 构建应用:使用缓存

    仪表板应用程序:

    1. 安装模块:使用缓存
    2. 构建应用:使用缓存

    总时间:

    real    0m2.933s
    user    0m0.309s
    sys     0m0.427s
    

    Third build (第一个应用程序中的代码变化很小):

    家庭应用程序:

    1. 安装模块:使用缓存
    2. 构建应用程序:50.04s

    仪表板应用程序:

    1. 安装模块:使用缓存
    2. 构建应用:使用缓存

    总时间:

    real    0m58.216s
    user    0m0.340s
    sys     0m0.445s
    

    Initial build 无Docker的家庭应用:89.69s

    real    1m30.111s
    user    2m6.148s
    sys     2m17.094s
    

    Second build 没有Docker的家庭应用程序 迪特 文件夹存在于磁盘上(无代码或依赖项更改):18.16s

    real    0m18.594s
    user    0m20.940s
    sys     0m2.155s
    

    Third build 没有Docker的家庭应用程序 文件夹存在于磁盘上(代码变化很小):20.44s

    real    0m20.886s
    user    0m22.472s
    sys     0m2.607s
    

    在Docker容器中,应用程序的第三次构建要长2倍。这表明,如果第一次生成的结果在磁盘上,则其他生成的完成速度更快。在Docker容器中,第一个之后的所有程序集只要第一个就执行,因为没有 迪特 文件夹。

    1 回复  |  直到 5 年前
        1
  •  1
  •   David Maze    6 年前

    在构建图像的过程中,您不能使用卷,无论如何,Docker已经完成了您要求的缓存。如果你离开你的 Dockerfile 保持原样,不要尝试将代码添加到 docker-compose.yml ,您应该获得构建的javascript文件的缓存,并按预期访问重建。

    当你跑步时 docker build Docker依次查看每一步。如果步骤的输入没有更改,步骤本身没有更改,并且添加的任何文件没有更改,那么Docker将重新使用以前运行该步骤的结果。在你的 文档文件 如果您只更改nginx配置,它将跳过所有的javascript构建步骤,并重新使用之前的结果。

    (您已经掌握的另一种相关技术是通过两个步骤构建应用程序:第一个步骤是在类似 package.json yarn.lock 这将命名依赖项并安装依赖项;然后复制并构建应用程序。由于“安装依赖项”步骤经常是耗时的,并且依赖项变化相对较少,因此您希望鼓励Docker重用上一个构建的 node_modules 目录。)

        2
  •  0
  •   Ryabchenko Alexander    5 年前

    如果您使用的是多阶段构建,那么Docker缓存存在问题。最终图像没有具有构建步骤的层。通过使用 --target --cache-from 您可以一起保存这些层并在重建中重用它们。

    你需要这样的东西

    docker build \
      --target build-home \
      --cache-from build-home:latest \
      -t build-home:latest 
    
    
    docker build \
      --target build-dashboard \
      --cache-from build-dashboard:latest \
      -t build-dashboard:latest 
    
    
    docker build \
      --cache-from build-dashboard:latest \
      --cache-from build-home:latest \
      -t my-image:latest \
    

    有关详细信息,请访问 https://andrewlock.net/caching-docker-layers-on-serverless-build-hosts-with-multi-stage-builds---target,-and---cache-from/