Nerd For Tech
Published in

Nerd For Tech

Working with OneDev Cache

CI/CD jobs running in a container always starts with a clean environment, and can be slow as it can not reuse files downloaded/generated in previous run of the job. To solve this issue, OneDev provides the ability to cache specified container directories to make them live through different runs of jobs.

Define Job Cache

Caches can be defined in more settings of a job like below:

Here cache key identifies a cache. Caches with same key can be re-used across different projects or jobs, even if the path is different, and caches with different keys will not be re-used even if path is the same.

How it Works

Cache is local to the node running the job. If a job runs on node1 to populate a cache, it will not benefit from this cache if subsequent runs happen on node2, unless cache on node2 also gets populated. Under the hood, OneDev allocates a host directory identified by cache key and mounts it into the container as cache path, so that it won’t be destroyed after job container is destroyed.

Also if there are multiple jobs running concurrently on same node declaring same cache key, OneDev will allocate multiple host directories under that key to make sure a single cache directory is only used by a single job at the same time to avoid race conditions. Since this can consume considerable disk spaces, the cache TTL defined in job executor tells OneDev when to clean up the a non-used cache directories:

By default OneDev auto-discovers job executors and the default cache TTL is one week. Create an appropriate job executor and overrides the cache TTL if necessary.

Example Setup

Let’s check some example setup in this section.

1. Cache maven local repository of Java project

A typical Java maven project may download a lot of dependencies, and this can take a lot of time. It is crucial to cache the maven local repository holding downloaded dependencies. When running in container, the maven local repository is normally placed at /root/.m2/repository, so we can add a cache entry like below:

The cache key should be the same for all Maven projects, as we want to reuse the cache as much as possible

2. Cache npm packages of JavaScript project

A typical JavaScript project also downloads lots of npm packages, normally saved into directory node_modules under project root. We can cache this directory to speed up npm install like below:

In this example, we embed project path into the cache key to make it only reusable in same project. This is because different projects may have very different dependencies. Although npm install will resync the mounted node_modules to make sure they are consistent with current package-lock.json, too many files inside the cache may need to be changed if the cache is used by a different project previously, and this can make npm install running slow.

Please note that if the job runs inside a Kubernetes cluster, caching node_modules will cause the build to fail, as relative path cache is set up via symbol link which is not handled well by many npm packages. In this case, it is suggested to cache /root/.npm instead, and the cache key should not include project path as global npm cache works in an accumulative way.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store