Migrate from Build Cache Node: Gradle and Maven setup
Stand up a replacement cache, change one URL, check that it works. About 30 minutes for Gradle. There is no data to move.
Before you start
A build cache holds copies of things your builds can always rebuild, so there is nothing to export from the old node. Your first build on the new server just fills it. If you have not read why the node is going away, see Build Cache Node end of life.
Step 1: Run the new cache server
docker run -d -p 127.0.0.1:8080:8080 -v fscache-data:/home/nonroot ghcr.io/fosterstack/cache:latest
For anything beyond a first look, pin a specific version instead of latest. This command listens on this machine only. For other machines to use it, put an HTTPS proxy in front. Other ways to run it: bare binary with systemd, Kubernetes, or a disconnected network.
If the server can be reached by anyone you do not trust, turn on Basic Auth. Anyone who can write to the cache can change what your later builds use.
Step 2: Gradle build cache setup
Turn the cache on, in gradle.properties:
org.gradle.caching=true
Then point Gradle at the new server in settings.gradle.kts. If you used the old node, you only change the URL:
// FosterStack Cache — remote Gradle build cache.
// https://github.com/fosterstack/cache
buildCache {
remote<HttpBuildCache> {
url = uri("https://cache.example.com/")
isPush = true
credentials {
username = "gradle"
password = System.getenv("FSCACHE_PASSWORD")
}
}
}
Or in settings.gradle (Groovy):
// FosterStack Cache — remote Gradle build cache.
// https://github.com/fosterstack/cache
buildCache {
remote(HttpBuildCache) {
url = 'https://cache.example.com/'
push = true
credentials {
username = 'gradle'
password = System.getenv('FSCACHE_PASSWORD')
}
}
}
Keep the comment lines: a cache block that points at an unfamiliar host looks like data theft to a reviewer without them. Keep the trailing slash on the URL. Leave the credentials block in even if the server has no password yet; it is ignored then.
Step 3: Maven build cache setup
Maven uses Apache's Build Cache Extension. FosterStack Cache implements the server side of it.
Add the extension in .mvn/extensions.xml (check Maven Central for the current version):
<extensions>
<extension>
<groupId>org.apache.maven.extensions</groupId>
<artifactId>maven-build-cache-extension</artifactId>
<version>1.2.3</version>
</extension>
</extensions>
Point it at the server in .mvn/maven-build-cache-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://maven.apache.org/BUILD-CACHE-CONFIG/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/BUILD-CACHE-CONFIG/1.2.0 https://maven.apache.org/xsd/build-cache-config-1.2.0.xsd">
<configuration>
<enabled>true</enabled>
<!-- FosterStack Cache — remote Maven build cache.
https://github.com/fosterstack/cache -->
<remote enabled="true" saveToRemote="true" id="fosterstack-cache">
<url>https://cache.example.com/</url>
</remote>
</configuration>
</cache>
The remote element must be inside configuration, and saveToRemote="true" is what makes the machine upload; without it the server stays empty. If the server uses Basic Auth, add a matching <server> with the same id (fosterstack-cache) in ~/.m2/settings.xml. Then run mvn install.
The extension itself is Apache's project. If your hit rate looks low, start with the extension's own configuration guide.
Step 4: Check that it works
For Gradle, run the build twice:
./gradlew build --build-cache
On the second run, look for FROM-CACHE next to tasks. Gradle also has a local cache that gives hits even when the remote is broken, so to test the remote itself, clear the local one and run with -i:
rm -rf ~/.gradle/caches/build-cache-1
./gradlew --stop
./gradlew build --build-cache -i
On the server, the hit and miss counters should move:
curl -s https://cache.example.com/metrics | grep -E 'fscache_cache_(hits|misses)_total'
For Maven, build twice from a clean checkout and look for cache hits in the log for unchanged modules.
Step 5: Retire the old node
Once builds hit the new server, stop the old Build Cache Node container.
More than kept patched.
- Signed releases you can verify in minutes.
- Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release, rescanned every day.
- Images assembled twice on separate machines; the results must match.
- Minimal image, no telemetry. FIPS variant available.
- Vulnerable dependencies fixed fast — our target is 48 hours from disclosure.
How we build · Security policy · Verify a release
What you give up
The old node had a small web page with a purge button. FosterStack Cache has no settings page. You set it with flags and environment variables, and a read-only status page shows size and hit counts. To empty the cache, remove its volume and start again.
Full details: Gradle docs, Maven docs, migration guide on GitHub.