Jenkins build cache setup with Cachely
Connect Nx, Lerna, Turborepo, Gradle, or Bazel to Cachely from Jenkins. Bind a workspace token from Jenkins credentials and share cached build outputs across agents and developer machines.
1. Choose your build tool
Create a workspace through the getting started guide. Jenkins runs your build; the build tool connects to Cachely using its own remote-cache protocol. Choose Nx or Lerna, Turborepo, Gradle, or Bazel below.
Use an agent with your project's pinned build tools and runtimes. Keep any dependency cache you already use. Cachely shares task outputs between builds; Jenkins stash is useful for passing files between stages of one Pipeline run. See Jenkins' stash documentation.
2. Add your Jenkins credential
For a pipeline whose users and build code you trust, generate one read-write Cachely token. Add it as a Jenkins Secret text credential with ID cachely-token in your job's folder. This lets builds read and populate the cache, including trusted pull-request builds. The example below requires Jenkins' Credentials Binding plugin.
You choose which builds may write. If users you do not trust can trigger the pipeline or change the code it runs, use the optional read-only setup for those builds.
3. Add the pipeline
This Jenkinsfile reads and writes cached outputs. The example runs Gradle; replace the contents of sh with the recipe for your tool below. Each recipe reads CACHELY_TOKEN from the binding and maps it to its tool's settings:
// Jenkinsfile
pipeline {
agent any
stages {
stage('Build') {
steps {
withCredentials([string(
credentialsId: 'cachely-token',
variable: 'CACHELY_TOKEN'
)]) {
sh '''
set +x
export GRADLE_CACHE_TOKEN="$CACHELY_TOKEN"
export GRADLE_CACHE_PUSH=true
./gradlew build --build-cache
'''
}
}
}
}
}A Pipeline loaded from SCM checks out its source by default. Keep your existing checkout, agent selection, and build tasks if you already have a Jenkinsfile. The shell examples require a Unix agent. Node builds need Node and your package manager; Gradle needs a JDK; Bazel needs your Bazel toolchain. For Android, the agent also needs the SDK and the JDK required by your Android Gradle Plugin.
Use single-quoted Groovy shell strings and do not print tokens. Masking limits accidental log exposure; it cannot stop build code that has access to a secret from extracting it. Keep trusted credential-bearing builds off agents shared with untrusted jobs. See Jenkins' credential binding guidance.
Nx and Lerna on Jenkins
Put these commands inside the credential-bound sh block above, on an agent with your pinned Node version. Replace my-appwith your cacheable target. See Nx setup for supported versions and output configuration.
set +x
npm ci
export NX_SELF_HOSTED_REMOTE_CACHE_SERVER=https://remote.cachely.dev
export NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN="$CACHELY_TOKEN"
npx nx build my-appFor Lerna, keep the exports and replace the final command with npx lerna run build. Lerna uses Nx's cache and the same token.
Turborepo on Jenkins
Use a Node agent and configure task outputs as described in Turborepo setup. This shell block uses the bound token for remote reads and writes:
set +x
npm ci
export TURBO_API=https://remote.cachely.dev
export TURBO_TOKEN="$CACHELY_TOKEN"
export TURBO_TEAM=cachely
npx turbo run build --summarizeSee Turborepo's cache option for the client settings if you want to change the default.
Gradle on Jenkins
Add the Gradle HttpBuildCache settings and use the Gradle Wrapper command in the pipeline above. It maps the bound token to GRADLE_CACHE_TOKEN and enables uploads with GRADLE_CACHE_PUSH=true. Keep your existing Android tasks and SDK setup for an Android project. No Cachely Gradle plugin is needed.
Bazel on Jenkins
On an agent with your project's pinned Bazel version and toolchain, put this inside the credential-bound shell block. It provides the token at runtime; keep credentials out of committed rc files. See Bazel setup.
set +x
bazel build //... --remote_cache=https://remote.cachely.dev --remote_header="Authorization=Bearer $CACHELY_TOKEN"Keep the enclosing Groovy shell string single-quoted so the shell expands the token. Restrict access to the agent and build logs because the command carries a secret header. See Bazel's remote-cache documentation.
Optional: limit writes for untrusted builds
Keep the single-token setup when you trust everyone who can run or modify the pipeline and the code it builds. If some builds should only download cached outputs, give those jobs a separate read-only credential. Keep the read-write credential in a folder available only to jobs you trust.
- Nx and Lerna: use the read-only token; Cachely enforces its permissions.
- Turborepo: also add
--cache=local:rw,remote:rto the build command. - Gradle: also set
GRADLE_CACHE_PUSH=false. - Bazel: also add
--remote_upload_local_results=false.
An if or when condition in a Jenkinsfile does not protect the read-write credential: anyone who can edit the file can request credentials available to that job. Follow Jenkins' credential scoping guidance. A read-only token still allows downloads; if a build should not access private outputs, omit the withCredentials block and remote-cache configuration.
4. Prove the second agent reads remotely
Run a build to populate the cache, then repeat the same revision, dependencies, and tasks on a fresh agent using the same credential. Do not restore task outputs or a local build cache for this check. Confirm matching reads in the Cachely dashboard.
- Nx and Lerna: look for
[remote cache]and restored outputs. On persistent agents, use the Nx verification steps to clear the local task cache first. - Turborepo: check the
--summarizereport in.turbo/runsfor remote hits. - Bazel: look for
remote cache hitin the action summary on a fresh agent without a disk cache.
For Gradle, temporarily disable the local build cache inside the existing settings block. Use the same configuration for both runs, populate the cache, then run the same revision and tasks on a clean agent:
// settings.gradle.kts, inside buildCache { ... }
local { isEnabled = false }Keep the Gradle exports from the pipeline and run ./gradlew clean build --build-cache --info. Look for FROM-CACHE on cacheable tasks and matching reads in the Cachely dashboard. A persistent Jenkins agent can otherwise report local hits, and clean removes build outputs without clearing Gradle's local cache. Restore the local-cache setting after the check.
If Jenkins cannot find the credential, check its ID, kind, and folder scope. For a Cachely 401, check the token binding; for a 403 during upload, check the token scope and upload flag. See cache troubleshooting for task-input and version differences that cause misses.
Connect another pipeline
For another CI provider, see CircleCI build cache setup or the CI setup hub.