gitlab-runner中使用docker模式,设置volumes将yarn的全局缓存保存到数据卷中问题

问题描述

在设置gitlab-runner中模式选为docker

问题出现的平台版本

yarn -v
v1.22.5
node -v
v16.3.0
docker -v
Docker version 20.10.7, build f0df350
gitlab-runner -v

Version:      13.12.0
Git revision: 7a6612da
Git branch:   13-12-stable
GO version:   go1.16.3
Built:        2021-05-20T23:59:54+01:00
OS/Arch:      darwin/amd64

相关代码

这个是我的gitlab-runner config
/usr/local/share/.cache/为镜像中yarn的全局缓存目录

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "xxxx"
  url = "http://xxxxx"
  token = "xxxxxx"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
  [runners.docker]
    tls_verify = false
    image = "node"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/Users/xxxx/home/cache:/usr/local/share/.cache/"]   

这个是我.gitlab-ci.yml文件

image: node

stages:
  - build

variables:
  GIT_STRATEGY: clone

build:
  stage: build
  image: node
  script: 
    - yarn install
  only:
    - feature/1.0.0
  tags:
    - fe
  timeout: 10m

你期待的结果是什么?实际看到的错误信息又是什么?

在ci执行到script时,yarn会显示网络错误,我确保我挂靠到volumes的文件权限为777
在docker外部访问/Users/xxxx/home/cache目录能够看到yarn下载的依赖内容

$ yarn install --har
yarn install v1.22.5
[1/5] Resolving packages...
[2/5] Fetching packages...
info There appears to be trouble with your network connection. Retrying...
info There appears to be trouble with your network connection. Retrying...

我期待得到的结果是我的依赖安装完成。

阅读 6.8k
2 个回答

确认几个点吧:

  • yarn cache dir 确认一下全局的缓存目录是否正确
  • yarn cache list 查看当前缓存的依赖库

由于评论不好写代码,我就补充一下我的回答吧!

我自己对你的环境做了一下模拟:

  1. 在基于 node:12 镜像运行的 容器 A 中,创建了一个 demo 的项目,同时对容器内的缓存目录做了一下映射:
docker run --rm -it --name node_1 \
-v /tmp/node_cache:/usr/local/share/.cache node:12 bash

# 下面是在容器内了
yarn global add @vue/cli
vue create demo

# 后面会将这个 demo 拷贝到另一个容器内
tar zcf demo.tgz demo
  1. 创建一个新的 容器 B,并挂载同样的缓存目录:
docker run --rm -it --name node_2 \
-v /tmp/node_cache:/usr/local/share/.cache node:12 bash
  1. 将 demo 从 容器 A 拷贝到 容器 B
docker cp node_1:/demo.tgz .
docker cp demo.tgz node_2:/
  1. 回到 容器 B 内,先删除 demo 下的 node_modules,然后我们尝试一下 yarn install --offline,看看是否成功:
tar zxf demo.tgz
cd demo
rm -rf node_modules
yarn install --offline

# 下面是输出结果
yarn install v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.3.2: The platform "linux" is incompatible with this module.
info "fsevents@2.3.2" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "linux" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 7.54s.

这样看来是没什么问题的:通过向容器挂载缓存目录达到加快下载依赖速度的目的,甚至不用下载依赖。

回到你的问题,有几个疑问点:

  • 你一开始挂载的缓存是从哪里来的?
  • 你为什么要改缓存目录的权限,在我上面的实验中,其实会发现我们并不需要改缓存目录的权限的。

所以可以考虑下:把容器内的缓存挂载到新的宿主机目录(比如 /tmp/cache2),然后第一次先让容器下载缓存,再观察第二次是否需要下载缓存(第二次的时候可以尝试开启离线模式,即 yarn install --offline

yarn install这个命令是在node这个镜像里面执行的,网络异常可能是因为默认镜像源的问题,可以在yarn instll 前加上
yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global
设置为国内镜像源试下,如果还是不行可以手动执行docker run -it node 运行node容器,在容器里面执行yarn instll 排查问题,包括网络、镜像源和dns等问题。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏