Woodpecker CI 使用技巧:npm 缓存

问题

在使用持续集成平台时,常会遇到一个痛点:为了确保构建的健壮性,每次构建都会在一个全新且隔离的容器环境中执行。

然而,如今大多数项目在构建过程中都需要下载大量依赖库。虽然常见的包管理工具通常会对已下载的库进行缓存,但由于我们每次都处于全新的隔离环境,缓存机制无法发挥作用,导致依赖重复下载,严重影响构建效率。

背景

针对 Woodpecker,有一个较为变通的方法可以规避这一问题。

当使用 Docker 作为构建代理时,Woodpecker 提供了环境变量 WOODPECKER_BACKEND_DOCKER_VOLUMES,用于在构建的所有步骤中挂载 volumes。该选项本意是给容器挂载宿主机的 SSL 证书或时区配置等文件,但在我们的场景下,也可以用来挂载 npm 的缓存目录,从而实现依赖缓存的复用。

实践

在 Woodpecker 的 Docker Agent 中,可以通过添加以下环境变量配置来实现缓存挂载:

  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:v3
    environment:
      WOODPECKER_BACKEND_DOCKER_VOLUMES: /root/woodpecker/npm:/root/.npm:rw

这里有几个需要注意的地方:

  • 无需额外配置 volumes:因为 Agent 直接挂载了宿主机的 Docker socket,可以自主管理卷的挂载。
  • 路径必须使用绝对路径:配置中的宿主机路径(如 /root/woodpecker/npm)不能使用相对路径,否则会导致挂载失败。

这就实现了将宿主机上的 /root/woodpecker/npm 文件夹挂载到构建步骤中每一个容器的 /root/.npm 目录,而该路径正是 npm 默认的缓存目录。

这样一来,所有构建步骤共享同一份本地缓存,既避免了每次从零下载依赖,又显著提升了构建速度。

后记

其实不只 npm 可以这么搞,gradle / go / uv 什么的也可以…

参考