Infrastructure worth keeping — and kept patched.

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.

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.

FosterStack Cache on GitHub FosterStack home