3

我有一个像这样的 Dockerfiles

# 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

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

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

我已经停在这个阶段,因为我不明白如何添加volumedocker-composefirst 创建的build-home阶段,然后将其添加volumebuild-dashboard. 也许我应该创建两个卷并将每个卷附加到每个构建阶段,但是如何做到这一点?

更新:

初始构建。

家庭应用:

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

仪表板应用:

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

总时间:

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

第二次构建(没有代码或依赖项更改):

家庭应用:

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

仪表板应用:

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

总时间:

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

第三次构建(第一个应用程序中的代码更改很小):

家庭应用:

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

仪表板应用:

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

总时间:

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

没有 Docker 的家庭应用程序的初始构建:89.69s

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

没有Docker的家庭应用程序的第二次构建dist,该文件夹存在于磁盘上(没有代码或依赖项更改):18.16s

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

没有 Docker 的家庭应用程序的第三次构建dist,该文件夹存在于磁盘上(代码更改很小):20.44s

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

在 docker-container 中,应用程序的第三次构建要长 2 倍。这表明如果第一个构建的结果在磁盘上,其他构建完成得更快。在docker容器中,第一个之后的所有程序集都与第一个一样执行,因为没有dist文件夹。

4

2 回答 2

3

如果您使用的是多阶段构建,那么 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/找到更多详细信息

于 2019-07-09T09:55:56.177 回答
0

您不能在映像构建期间使用卷,并且无论如何 Docker 已经完成了您要求的缓存。如果您Dockerfile保持原样并且不尝试将您的代码添加到 中的卷中docker-compose.yml,您应该可以缓存已构建的 Javascript 文件访问重建,如您所愿。

运行时docker build,Docker 会依次查看每个步骤。如果步骤的输入没有改变,步骤本身没有改变,并且正在添加的任何文件都没有改变,那么 Docker 将重用之前运行该步骤的结果。在您的Dockerfile中,如果您只更改 nginx 配置,它将跳过所有 Javascript 构建步骤并重用它们之前的结果。

(您已经拥有的另一种相关技术是分两步构建应用程序:首先复制类似package.jsonyarn.lock名称依赖项的文件,然后安装依赖项;然后复制并构建您的应用程序。由于“安装依赖项”步骤经常耗时且依赖项更改相对较少,您希望鼓励 Docker 重用上次构建的node_modules目录。)

于 2018-10-08T11:29:58.940 回答