Gitlab CI:如何从预建图像缓存 node_modules?

Posted

技术标签:

【中文标题】Gitlab CI:如何从预建图像缓存 node_modules?【英文标题】:Gitlab CI : how to cache node_modules from a prebuilt image? 【发布时间】:2020-12-08 14:00:31 【问题描述】:

情况是这样的: 我在 Gitlab CI(由 vue-cli 启动)中运行赛普拉斯测试。为了加快执行速度,我构建了一个包含必要依赖项的 Docker 映像。 如何从预建映像缓存 node_modules 以在测试作业中使用它? 目前我正在使用一个糟糕(但有效)的解决方案:

testsE2e:
  image: path/to/prebuiltImg
  stage: tests
  script:
    - ln -s /node_modules/ /builds/path/to/prebuiltImg/node_modules
    - yarn test:e2e
    - yarn test:e2e:report

但我认为使用 Gitlab CI 缓存必须有一种更清洁的方式。

我一直在测试:

cacheE2eDeps:
  image: path/to/prebuiltImg
  stage: dependencies
  cache:
    key: e2eDeps
    paths:
      - node_modules/
  script:
    - find / -name node_modules # check that node_modules files are there
    - echo "Caching e2e test dependencies"

testsE2e:
  image: path/to/prebuiltImg
  stage: tests
  cache:
    key: e2eDeps
  script:
    - yarn test:e2e
    - yarn test:e2e:report

但作业 cacheE2eDeps 显示 "WARNING: node_modules/: no matching files" 错误。 我怎样才能成功地做到这一点? Gitlab 文档并没有真正谈论从预建图像中缓存...

用于构建镜像的 Dockerfile :

FROM cypress/browsers:node13.8.0-chrome81-ff75

COPY . .
RUN yarn install

【问题讨论】:

【参考方案1】:

没有关于从预建图像缓存数据的文档,因为它根本没有完成。映像中已经存在依赖项,那么为什么要首先缓存它们呢?这只会导致不必要的数据重复。

此外,您似乎认为缓存应该用于在作业之间共享数据,但它的主要用例是在同一作业的不同运行之间共享数据。应使用工件在作业之间共享数据。

在您的情况下,您可以使用缓存而不是预构建的图像,如下所示:

variables:
  CYPRESS_CACHE_FOLDER: "$CI_PROJECT_DIR/cache/Cypress"

testsE2e:
  image: cypress/browsers:node13.8.0-chrome81-ff75
  stage: tests
  cache:
    key: "e2eDeps"
    paths:
      - node_modules/
      - cache/Cypress/
  script:
    - yarn install
    - yarn test:e2e
    - yarn test:e2e:report

第一次运行上述作业时,它会从头开始安装依赖项,但下次它会从运行器缓存中获取它们。需要注意的是,除非所有运行此作业的运行器共享缓存,否则每次在新运行器上运行它时,它都会从头开始安装依赖项。

这是documentation 关于在 GitLab CI 中使用 yarn。

编辑:

详细说明使用缓存与工件 - 工件既用于存储作业输出(例如,稍后手动下载),也用于将一个作业的结果从后续阶段传递给另一个作业,而缓存旨在加速通过保留作业需要从 Internet 下载的文件来执行作业。详情请见GitLab documentation。

node_modules目录的内容显然属于第二类。

【讨论】:

非常感谢,我对缓存系统不是很了解。现在我遇到了另一个与赛普拉斯相关的问题,带有以下错误消息:- You're caching 'node_modules' but are not caching this path: /root/.cache/Cypress 问题是将/root/.cache/Cypress 添加到缓存路径失败(即使该文件夹存在)因为看起来像/root 的权利问题( whoami 返回“root”)。 实际上问题是 GitLab Runner 无法缓存任何不在构建目录中的内容。以下是解决此问题的方法:github.com/cypress-io/cypress/issues/7683 我更新了我的答案以包括 CI 的赛普拉斯配置。 添加 CYPRESS_CACHE_FOLDER 变量有效,我的 CI 现在很棒,再次感谢! 这是正确的答案,但我们缺少关于 “我应该为 node_modules 使用工件而不是缓存吗?”的信息

以上是关于Gitlab CI:如何从预建图像缓存 node_modules?的主要内容,如果未能解决你的问题,请参考以下文章

Heroku:如何在 gitlab CI/CD 中发布现有图像?

如何使用 CI/CD 为 Gitlab 注册表推送基于 docker compose 的图像

【Gitlab ci】 缓存

Jenkins+GitLab+Sonarqube+Shell持续集成CI/CD

利用gitlab-ci实现前端流水线。

如何使用 gitlab CI 解决 Angular 业力测试的 chrome 错误?