The Gradle build cache node software is a freely available HTTP remote cache server for Gradle’s build caching functionality. This manual covers obtaining, installing and operating one or more build cache nodes.

Use of Gradle’s build cache node software is subject to the Gradle Terms of Use.

Build cache nodes can optionally be connected with Develocity for centralized management and monitoring, and to enable replicating cache entries between multiple nodes. The connection to Develocity also allows the usage of the build cache node for Bazel and Maven remote caching.

The build cache node is distributed as a Docker image via Docker Hub, and as a executable JAR. Both distributions offer the same functionality.

Requirements

Data directory disk usage

The build cache node requires a single directory, referred to as the “data directory”, to store its cache entries and other files. The default size of the cache is 10 GiB. The build cache node will use a few 10s of MiB’s more than the cache size to store log files, config files and other operational files.

CPU & memory

By default, the build cache node uses up to about 1.5 GiB of memory.

The build cache node does not require significant CPU resources. Performance is generally constrained by network access to the build cache node.

Installation

There are 3 different installation types: JAR, Docker, Kubernetes. Choose the one that is most suitable to your environment.

JAR

You can download version 20.0 of the JAR here.

Older versions of the JAR can be found in the appendix below.

Java runtime

Version 15.0 and later of the build cache node JAR require at least Java 17 to run.

Version 9.0 and later of the build cache node JAR require at least Java 11 to run.

Version 7.0 and later require at least Java 8.

Version 6.0 and older require Java 8.

Running

Once you have downloaded the JAR file, it can be run simply with java command and the start subcommand:

java -jar build-cache-node-20.0.jar start

This will start the node with a data directory inside the $TEMP location and listening on ports 5071 and 6011 (for Bazel remote caching).

Specifying a data directory

It is strongly recommended to specify an explicit data directory location with the --data-dir option:

java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node

Each build cache node must have its own data directory. Sharing a data directory between cache nodes is not supported.

To use the current directory as the data directory, use --data-dir .

Specifying a configuration directory

Location of the configuration directory can be overridden with the --config-dir option:

java -jar build-cache-node-20.0.jar --config-dir /opt/build-cache-node/custom-config-dir

This option overrides the default location of configuration directory, which is «data-dir»/conf (where «data-dir» is the build cache node’s data directory).

«data-dir» is a placeholder referring to the build cache node’s data directory. The actual text «data-dir» cannot be specified when setting --config-dir.

Providing a config file

If you provide a custom config file («config-dir»/config.yaml), note that it must be writable. The build cache node will update the configuration file when build cache settings are changed in the user interface or in Develocity. The build cache node will also update the configuration file when it is upgraded from earlier versions of the build cache node (to update the configuration file to the latest schema).

If you’re trying to use an immutable source for the configuration, one solution is to mount or write the configuration to a temporary file, then copy that file to config.yaml. If you do this, config updates from the build cache node will not be written back to your config source.

«config-dir» is a placeholder referring to the build cache node’s configuration directory.

Specifying the ports

The default listening ports are 5071 and 6011 (the latter is for Bazel remote caching).

With regard to the former, to use a different port you can use the --port option:

java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --port 443
Most systems require super user privileges to bind to a port lower than 1024.

In the absence of a --port option, the PORT environment variable is also respected.

You can configure the port For Bazel remote caching with --config grpcServer.port=«port-number»:

java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --config grpcServer.port=6012

Specifying the application base path

The default path used to access the build cache node is “/”. For example the build cache node UI is available under the root path (e.g, http://localhost:5071/).

To use a different path, use the --path option:

java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --port 443 --path my-path

In the above example, the build cache node UI is available at https://localhost/my-path/, the URL to use when configuring Gradle or Maven is https://localhost/my-path/cache/, and the remote cache endpoint for Bazel is \grpcs://localhost:6011/.

Optimized HTTPS

The build cache serves HTTPS traffic more efficiently on some platforms. If HTTPS is configured but optimized HTTPS support could not be loaded, the application will emit a warning to the console of:

WARNING: Unable to use optimized HTTPS support as OpenSSL was not found.

Currently, optimized HTTPS support is available on the following platforms:

  • Linux (aarch_64/x86_64)

  • macOS (aarch_64/x86_64)

  • Windows (x86_64)

Auto start

The build cache node JAR provides no built-in mechanism for auto starting on system restart. This must be implemented with your operating system’s process manager or similar.

The following demonstrates how to use systemd, a popular process manager for Linux systems, to achieve this.

1. Create a file, build-cache-node.sh as root and make it executable, with the following contents:

#!/bin/bash
# Launches Gradle Remote Build Cache node with correct arguments
# Should be run with CAP_NET_BIND_SERVICE rather than as the superuser
java -jar /absolute/path/to/build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --port 80

2. Create a file, /etc/systemd/system/gradle-remote-build-cache.service as root, with the following contents:

[Unit]
Description=Gradle Remote Build Cache
After=network.target
StartLimitIntervalSec=0

[Service]
# To improve security you should create a separate user to run the Build Cache Node
#User=gradle
#Group=gradle
# Allow using ports below 1024, required if not run as the superuser
AmbientCapabilities=CAP_NET_BIND_SERVICE
Restart=always
RestartSec=1
ExecStart=/absolute/path/to/build-cache-node.sh

[Install]
WantedBy=multi-user.target

3. Run the following to start the build cache node for the first time:

systemctl start gradle-remote-build-cache

4. Run the following to have systemd start the build cache node on system boot:

systemctl enable gradle-remote-build-cache

Docker

Installation

With Docker installed, starting a build cache node is as simple as the following command:

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 80:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start

This will download the latest version of the build cache node container image, create a new container from it, then run it with the UID of the current user. The cache node will use /opt/build-cache-node on the host to store its files and serve on ports 80 and 6011. More information about changing these settings can be found in the following sections.

Airgapped installation

In order to install the Docker build cache node on a host that is not connected to the Internet (i.e. airgapped), you will need to first obtain the image on an Internet connected host, then transfer it to the airgapped destination.

  1. On the non-airgapped system, pull down the latest docker image for the node

    docker pull gradle/build-cache-node:20.0
  2. Export the image to a file

    docker save gradle/build-cache-node:20.0 --output build-cache-node.tar
  3. Copy this file across to the airgapped host, and then import the image into docker

    docker load --input build-cache-node.tar

The node can then be started and configured on the airgapped host in the same manner as a non-airgapped install:

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 80:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start

Versioning

It is generally desirable to always use the most recent version of the build cache node. An exception to this is if you are attaching the node to a Develocity installation that is not up-to-date as each major version of the build cache node has a minimum Develocity version requirement. These minimum versions can be found in the Develocity compatibility document.

The docker latest tag always refers to the most recently released version of the build cache node, however we recommend using an absolute version when using docker, as latest may give unexpected results when upgrading due to Docker idiosyncrasies.

Support for build cache node versions older than 14.0 is ending. Discontinued versions of the build cache node will stop being distributed as of December 2024. Versions older than 14.0 will not be able to connect to Develocity 2024.3 and above.

Binding the data directory

The build cache node container uses /data inside the container as the application data directory. When starting the container, the --volume (or -v) switch should be used to specify which directory on the host to mount to this directory in the container.

The command below demonstrates using the /opt/build-cache-node directory on the host as the data directory for the build cache node:

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 80:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start
If the container is started without a mount for /data, Docker will create a directory on the host in a location of its choosing to use.

Each build cache node must have its own data directory. Sharing a data directory between cache nodes is not supported.

When choosing where to store the cache data (i.e. which host directory to mount to /data within the container), be sure to choose a disk volume that has adequate storage capacity for your desired cache size.

For more information on managing data volumes with Docker, please see this tutorial.

Run-as user

The build cache node docker image does not specify a default user. If a container is started without --user specified, the build cache node application will run as the root user. While Docker containers provide a kind of process sandbox, it is generally recommended to avoid running processes as root inside containers.

Previously, we showed starting the node with the current user by using the arguments --user $UID. If you wish to use a different user ID known to the host, you can replace this $UID with the required user ID.

The command below demonstrates using a user id of 5000 for running the cache node:

docker run --detach \
    --user 5000 \
    --volume /opt/build-cache-node:/data \
    --publish 80:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start

The build cache node application will read from and write to the file system as this user. The /data directory mount must be readable and writable by this user.

Port mapping

The cache node container exposes the ports 5071 and 6011. Each port must be mapped to a port on the host in order to expose it.

It is recommended to map the HTTP port (5071 by default) to a standard one on the host in order to avoid the need to specify the port number when accessing the cache node. This can be done with --publish 80:5071 for HTTP and --publish 443:5071 for HTTPS.

To expose the application via different ports, simply use a different number for the preceding number in each --publish (or -p) argument. The following command exposes traffic via port 8443 on the host:

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 8443:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start
if you are not using Bazel and do not wish to expose its port, you can remove it from the mappings, effectively "hiding" it.

Specifying the application base path

The default path used to access the build cache node is “/”. For example the build cache node UI is available under the root path (e.g, http://localhost:5071/).

To use a different path, use the --path option:

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 8443:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0\
    start
    --path my-path

In the above example, the build cache node UI is available at https://localhost/my-path/, and the URL to use when configuring Gradle or Maven is https://localhost/my-path/cache/.

Auto start

The build cache node container can be automatically restarted on system boot by leveraging Docker’s restart policies. Starting a build cache node container with --restart always will ensure that it is always running unless explicitly stopped.

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 80:5071 \
    --publish 6011:6011 \
    --restart always \
    gradle/build-cache-node:20.0 \
    start

Kubernetes

Below is a sample Kubernetes manifest for deploying a build cache node to a Kubernetes cluster.

A persistent volume is mounted to bind the data directory to, and it should be sized appropriately for the target cache size.

The Storage Class variate from your Kubernetes cluster, so you may need to adjust the storageClassName attribute accordingly.

You may also need to adjust the allocated CPU and memory resources based on the needs of your build cache and the resources of your cluster.

apiVersion: v1
kind: Service
metadata:
  name: build-cache-node
spec:
  selector:
    app.kubernetes.io/part-of: gradle-enterprise
    app.kubernetes.io/component: build-cache-node
  ports:
  - name: http
    port: 5071
  - name: grpc-bazel
    port: 6011
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: build-cache-node
  labels:
    app.kubernetes.io/part-of: gradle-enterprise
    app.kubernetes.io/component: build-cache-node
spec:
  selector:
    matchLabels:
      app.kubernetes.io/part-of: gradle-enterprise
      app.kubernetes.io/component: build-cache-node
  serviceName: build-cache-node
  template:
    metadata:
      labels:
        app.kubernetes.io/part-of: gradle-enterprise
        app.kubernetes.io/component: build-cache-node
    spec:
      containers:
      - name: build-cache-node
        image: gradle/build-cache-node:20.0
        args: [ "start" ]
        ports:
        - name: http
          containerPort: 5071
        - name: grpc-bazel
          containerPort: 6011
        resources:
          requests:
            memory: 1Gi
            cpu: 0.5
          limits:
            memory: 2Gi
            cpu: 1.5
        env:
        - name: EXCLUSIVE_VOLUME_SIZE
          value: "10Gi" # Change this to the appropriate storage size
        volumeMounts:
        - mountPath: /data
          name: build-cache-node-data-volume
  volumeClaimTemplates:
  - metadata:
      name: build-cache-node-data-volume
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: '10Gi' # Change this to the appropriate storage size
      storageClassName: 'standard' # Change this to the appropriate storage class
This manifest configures the build cache node to automatically use all of the provided disk volume via the EXCLUSIVE_VOLUME_SIZE environment variable. For more details, see the Using a fixed size exclusive data volume section.

Providing a config file from a secret

The Build Cache config file can be provided as a secret in Kubernetes. However, by default, mounted secrets are read-only for security reasons. While enabling read-write access is technically possible, it requires disabling a security feature and applies globally across your cluster, potentially exposing sensitive information unintentionally. For details, refer to this discussion: (see this comment).

We recommend a more secure approach: create a read-only secret for the configuration file. This ensures sensitive data remains protected while maintaining the functionality of the Build Cache Node.

Note that this approach, makes the config file immutable and changes made through the UI or Develocity will not be reflected in your secret. See the “Providing a config file” section for more details.
Creating the secret

Use the following kubectl command to create the secret named gradle-build-cache-config-secret within the desired namespace. Replace <remote-bcn-ns> with the actual namespace:

kubectl -n <remote-bcn-ns> create secret generic gradle-build-cache-config-secret --from-file=config.yaml
apiVersion: v1
data:
  config.yaml: dmVyc2lvbjogNQpyZWdpc3RyYXRp.... # Base64 encoded configuration file
kind: Secret
metadata:
  name: gradle-build-cache-config-secret
  namespace: <remote-bcn-ns>
type: Opaque
Any changes to the config file require recreating the secret and restarting the Build Cache pod.
Updating the manifest

The following Kubernetes manifest loads the Build Cache Node configuration from a secret named gradle-build-cache-config-secret:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: build-cache-node
  labels:
    app.kubernetes.io/part-of: gradle-enterprise
    app.kubernetes.io/component: build-cache-node
spec:
  selector:
    matchLabels:
      app.kubernetes.io/part-of: gradle-enterprise
      app.kubernetes.io/component: build-cache-node
  serviceName: build-cache-node
  template:
    metadata:
      labels:
        app.kubernetes.io/part-of: gradle-enterprise
        app.kubernetes.io/component: build-cache-node
    spec:
      initContainers:
      - name: config-mounter
        image: "busybox:1.33.0"
        command: [
          "sh",
          "-ce",
          "cp /tmp/config.yaml /data/conf/config.yaml" ]
        volumeMounts:
        - name: tmp-build-cache-config-file
          mountPath: /tmp
        - name: build-cache-config-dir
          mountPath: /data/conf
      containers:
      - name: build-cache-node
        image: gradle/build-cache-node:20.0
        args: [ "start" ]
        ports:
        - name: http
          containerPort: 5071
        - name: grpc-bazel
          containerPort: 6011
        resources:
          requests:
            memory: 1Gi
            cpu: 0.5
          limits:
            memory: 2Gi
            cpu: 1.5
        env:
        - name: EXCLUSIVE_VOLUME_SIZE
          value: "10Gi" # Change this to the appropriate storage size
        volumeMounts:
        - mountPath: /data
          name: build-cache-node-data-volume
        - name: build-cache-config-dir
          mountPath: /data/conf
      volumes:
      - name: build-cache-config-dir
        emptyDir: {}
      - name: tmp-build-cache-config-file
        secret:
          secretName: gradle-build-cache-config-secret
  volumeClaimTemplates:
  - metadata:
      name: build-cache-node-data-volume
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: '10Gi' # Change this to the appropriate storage size
      storageClassName: 'standard' # Change this to the appropriate storage class

Non-root user

By default, the build cache node application will run as the root user. It is possible to run as a non-root user by including a security context in the deployment manifest.

securityContext:
  runAsUser: 999
  runAsGroup: 0
  fsGroup: 0

Exposing the build cache node outside your cluster

The sample Kubernetes manifest includes a service for the build cache node named build-cache-node exposing port 5071 for accessing the application. This service uses a ClusterIP for communication meaning it is not accessible outside of the Kubernetes cluster by default. To access the build cache node outside of your cluster you will need to create some kind of entrypoint to this service into the cluster. Potential methods for this are via an ingress, explicit node port, external IP service or a load balancer. The method you choose depends on your cluster and network configuration.

Below is a sample Ingress definition:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: build-cache-node-ingress
spec:
  tls:
  - hosts:
    - {your-domain-name}
    secretName: {tls-secret-for-your-domain-name}
  rules:
  - host: {your-domain-name}
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: build-cache-node
            port:
              name: http
      - path: /bazel
        pathType: ImplementationSpecific
        backend:
          service:
            name: build-cache-node
            port:
              name: grpc-bazel

Using a fixed size exclusive data volume

You can use the --use-exclusive-volume-with-size option or the EXCLUSIVE_VOLUME_SIZE to have the build cache node use the specified size as the target cache size. The “free space buffer” setting will still be respected, with additional temporary space also being reserved.

This configuration is typically more convenient when the build cache node is deployed via a container runtime and the size of the disk volume allocated to the cache is declared as part of the deployment configuration, such as when deploying to a Kubernetes cluster. The same size configuration value used as part of provisioning the volume can be used as part of the build cache node start invocation, ensuring the cache uses as much space is available and removing the need to synchronize the size configuration in the config file.

Specifying the size of the fixed volume is necessary due to many storage providers not accurately reporting the size and free space of the volume to applications running inside the container the volume is attached to. When this option is used, the available space will be calculated based on the specified size instead of querying the file system directly.

It is critically important that the build cache node process is the only significant user of the disk volume when this option is in use. If there are other non-negligible files on the same disk volume, the build cache node may overestimate the space available and fill the disk.

The following examples demonstrate using this option.

java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --use-exclusive-volume-with-size 10Gi
EXCLUSIVE_VOLUME_SIZE=10Gi java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node

The size of the exclusive volume must be specified as the number of bytes, using Kubernetes Resource Quantity notation.

Post-installation setup

Configure UI access control

By default, access to the configuration user interface requires a generated username and password that is printed to the console on startup. It is recommended to change this to a username and password that you specify. See the “User interface access control” section for details.

Prior to version 10.0, the remote build cache node configuration user interface was initially accessible without a username and password.

Enable cache access

By default, access to the build cache is disabled. You will need to configure cache access after you install the build cache node before you will be able to use the remote build cache. See the “Cache access control” section for details.

Prior to version 10.0, read/write access to the cache by anonymous users was enabled by default.

Verify connectivity

The build cache node has a /ping HTTP endpoint to test connectivity, which can be used to test if it is reachable from a Develocity installation or reachable for users in general. For example, if you are running a build cache node locally, without SSL, and are using the default listening port, then you can access this endpoint at http://localhost:5071/ping.

Connectivity to a build cache node installation can be tested by running the following command on hosts / computers which need to connect to the build cache node:

curl -sw \\n --fail-with-body --show-error https://<build-cache-node-host>/ping

It should return SUCCESS.

Disk space management

The build cache node stores cache entries on disk, under the «data-dir»/system/cache directory. There are several configuration settings which control how much space the build cache will use to store cache entries. See the “Cache settings” section for more details on changing the disk space management settings.

Purging the cache

All of the entries of a build cache node can be purged via the node’s configuration page in Develocity or via the node’s own user interface. The purge will execute in the background, and it may take several minutes to remove all entries for large caches.

Logging

The logs for the build cache node are located in the «data-dir»/logs directory. Logs are automatically rotated. The latest log file is named node.log (the latest log file is always «data-dir»/logs/node.log).

Disaster recovery

The config directory («data-dir»/conf by default) stores all the critical information for a build cache node. A minimal disaster recover scheme involves backing up and restoring this directory, relying on subsequent builds to repopulate the build cache. An alternative option is to back up and restore the entire data directory, allowing the cache contents to be restored along with the configuration, minimising build performance disruptions, at the expense of larger and slower backups.

When the node is configured to connect to a Develocity installation, part of the configuration information is the public address that Develocity uses to initiate communication with the build cache node. When restoring configuration to a new installation, reestablishing Develocity connectivity requires the new installation to have the same public address or for the configuration to be updated post-restore.

The configuration of the built-in build cache node provided as part of Develocity is backed up as part of the Develocity back up mechanism and does not need to be backed up separately.

Configuration

The cache settings and Develocity connection settings can be configured via the build cache node’s web interface. Since version 4.2, configuration can also be specified by a config file for non-built-in nodes. Note that this file must be writable.

Configuring the node via the web interface is generally more convenient, while configuring via the configuration file is generally more appropriate for automated installations.

If you provide your own configuration file, see the “Providing a config file” section for details.

The built-in node will store its configuration in the connected Develocity instance’s database. Config files will be migrated to the database and then deleted. If there is already a configuration stored in the Develocity database, it will take precedence over any file migrations.

Accessing the configuration user interface

To access the build cache node’s configuration user interface, navigate to the build cache node’s base URL. For example, if you are running the build cache node locally, without SSL, and are using the default listening port, then you can access the configuration UI at http://localhost:5071.

When you first run the build cache node, a generated username and password is printed to the console. Use the generated username and password to log into the configuration UI for the first time. See the “User interface access control” section for details on how to change the UI access control.

If you have specified a non-root application path, then the configuration user interface is accessible under the application path (http://localhost:5071/my-app-path). See the “Specifying the application base path” section when running via a JAR or “Specifying the application base path” section when running via Docker for details on setting the application path.

Editing the file

The config file is stored at «data-dir»/conf/config.yaml, and is in YAML format. It is read at application startup, and is written to when the config is updated via the web interface.

The schema for the config file is versioned. Build cache node version 20.0 uses schema version 5. This schema is published in JSON schema format, and is available here.

The config file should always start with the schema version:

version: 5

The following is an example of a complete config file that may be used as a starting point:

version: 5
registration:
  serverAddress: "https://ge-hostname"
  nodeAddress: "https://node-hostname"
  key: "«key»"
  secret: "«secret»"
cache:
  targetSize:
    type: fixed
    size: 50000
  freeSpaceBufferSize: 2000
  maxArtifactSize: 5
  maxEntryAgeInHours: null
  accessControl:
    anonymousLevel: "read"
    users:
      ci-user:
        password: "«salt-hash-string»"
        level: "readwrite"
        note: "Continuous Integration User"
      developer:
        password: "«salt-hash-string»"
        level: "readwrite"
uiAccess:
  type: "secure"
  username: "myChosenUsername"
  password: "«salt-hash-string»"

The various sections will be explained below.

Generating password hashes

You can generate password hashes by running the build cache node application with the hash subcommand. This causes the application to prompt for a password and then emit a hash for use in the config file as a password value.

> java -jar path/to/build-cache-node-20.0.jar hash
Enter password:
Confirm password:
"7a+lG8aaYRGJCgDtsSrYcufys67tW1I/augaLUiN8As=:+Zv1/r2oY0T2anrooV8XVe6ovlCqBfOf2ZwgfoLA6Ew="
> docker run --interactive --tty gradle/build-cache-node:20.0 hash
Enter password:
Confirm password:
"7a+lG8aaYRGJCgDtsSrYcufys67tW1I/augaLUiN8As=:+Zv1/r2oY0T2anrooV8XVe6ovlCqBfOf2ZwgfoLA6Ew="

To generate hashes in a non-interactive mode, you can run the node application with hash --password <password-file> where <password-file> is the path to a file that contains the password to hash. To specify the password via standard input, specify - as the password file. You can then pipe the required password to the command:

> echo "$PASSWORD_ENV_VAR" | java -jar path/to/build-cache-node-20.0.jar hash --password -
"D3dyflAOczSzlnbKTyGaG8h8HU1wcU5kUH5/h7eySKY=:3QfbpLm5m6gvYBOY3kDbDMPuxpvKAj9ptaBPtDYDSy8="
> echo "$PASSWORD_ENV_VAR" | docker run --interactive gradle/build-cache-node:20.0 hash --password -
"D3dyflAOczSzlnbKTyGaG8h8HU1wcU5kUH5/h7eySKY=:3QfbpLm5m6gvYBOY3kDbDMPuxpvKAj9ptaBPtDYDSy8="
Piping the password using echo like shown above will leak the password into your shell’s command history. It is more secure to use --password <password-file> with a regular file.

Develocity registration

Build cache nodes can be registered and connected with a Develocity installation to enable extra features, such as centralized monitoring and cache entry replication. The registration can be configured via the web interface or via the config file.

You must first register the node with Develocity in order to obtain a key and secret for the node. Details on this process can be found in the Develocity Administration Manual.

The following is an example config file snippet for configuring the Develocity registration:

version: 5
registration:
  serverAddress: "https://ge-hostname"
  nodeAddress: "https://node-hostname"
  key: "«key»"
  secret: "«secret»"

Cache settings

The cache settings determine aspects of the build cache. They can be configured via the web interface or config file.

Target cache size

If adding a new cache entry increases the combined size of all cache entries over the target cache size, the least recently used cache entries will be evicted to make space.

This storage mode is called fixed size and it is the default. The target size value is configured in MiB, and defaults to 10 GiB.

The following is an example config file snippet for changing the target size to 50 GiB:

version: 5
cache:
  targetSize:
    type: fixed
    size: 50000

When the build cache is stored on a dedicated volume, type: maxAvailable is recommended to automatically utilize the available disk space. This should be used together with the “Free space buffer size” setting.

The following is an example config file snippet for changing the target size to use all of the volume’s available space except 2 GiB:

version: 5
cache:
  targetSize:
    type: maxAvailable
  freeSpaceBufferSize: 2000

Free space buffer size

In order to prevent the build cache from using all available disk space (which can lead to a number of problems), the build cache will attempt to maintain a minimum amount of free space on the disk.

If the amount of free space is less than the free space buffer size, then the target cache size will be reduced and the least recently used cache entries will be evicted until the specified amount of free space is made available. If the build cache is unable to maintain the free space buffer even after reducing the cache size to zero, it will reject new cache writes until enough free disk space is made available.

The value is defaulted to 1024 MiB (1 GiB). The minimum free space buffer size is 256 MiB. If you want to change the default value, we recommend allocating at least 5% of your total disk space for the free space buffer.

The following is an example config file snippet for changing the free space buffer size to 2 GiB:

version: 5
cache:
  freeSpaceBufferSize: 2000

Maximum artifact size

Attempts to store artifacts larger than this limit will be rejected. The default setting of 100 MiB is suitable for most builds and should only need to be increased if your builds produce large outputs that you wish to cache.

Please note that increasing this value may require further configuration changes in network components in your system (e.g. load balancer, firewall, proxy) to ensure that nothing blocks the upload of bigger artifacts to the Build Cache Node.

The following is an example config file snippet for changing the maximum artifact size to 200 MiB:

version: 5
cache:
  maxArtifactSize: 200

Maximum entry age

If enabled, cache entries will be evicted once they exceed the configured age (in hours). The age of an entry is the duration of time that passed since the entry was stored on the cache node. By default, no age limit is imposed.

This feature may be used by customers having security regulations in place that mandate cached artifacts must be evicted after a specific amount of time. It should be noted that this configuration option can impact the effectiveness of the build cache, as build cache entries are evicted regardless of how often a given artifact is used, when it was last used, or whether the target cache size has been reached or not.

The following is an example config file snippet for setting the maximum entry age to 24 hours:

version: 5
cache:
  maxEntryAgeInHours: 24

Omitting the option from the config file or setting it explicitly to null disables this additional eviction strategy.

version: 5
cache:
  maxEntryAgeInHours: null

Overview of default cache size settings

The Build Cache Node is configured with the following defaults:

If these default values match your requirements, then no further configuration is required for these settings. If not, please revisit the relevant sections linked above to configure the Build Cache Node further.

Cache access control

Build cache access can be disabled (the default), granted based on a set of credentials, or granted to anonymous users.

You can specify one or more credentials and whether they have Read or Read and Write access.

It is also possible to specify the access level (Read or Read and Write) for anonymous users. Specify None if you don’t want to allow anonymous access.

When the anonymous access level is set to Read and Write, writing to the build cache does not require credentials which may allow anyone to write malicious cache entries. It is strongly recommended to only enable Read and Write for anonymous users if your build cache node is on a secured network.

Refer to the Gradle user guide or the Develocity Maven Extension User Manual for details on how to specify credentials to use when accessing a cache.

Versions of the remote node prior to version 3.0 support a simpler permission model. The controls will be respectively different for such nodes.

At the top level of the cache section in the config file, you can optionally define a accessControl section specifying fine-grained access to the cache. If accessControl is not specified, the cache will be inaccessible (no one will be able to read or write from the cache).

The accessControl section can contain a list of user objects. The name of each user object is used as the username when authenticating with the build cache. Each user object has the following fields:

  • password (required) - the salt-hash-string of the user’s password. Use the hash subcommand to generate the password hash. See the “Generating password hashes” section for details.

  • level (required) - the user’s level of access to the build cache. The level field may have a value of "read" or "readwrite".

  • note (optional) - a string to describe the user and aid in administration.

The following is an example config file snippet for configuring two users with read and write access:

version: 5
cache:
  accessControl:
    users:
      ci-user:
        password: "«salt-hash-string»"
        level: "readwrite"
        note: "Continuous Integration User"
      developer:
        password: "«salt-hash-string»"
        level: "readwrite"

Anonymous access to the build cache can be configured by setting the anonymousLevel property, which can be set to "none", "read", or "readwrite". If no anonymousLevel is provided, then the default value of "none" is used.

The following is an example config file snippet for configuring read only anonymous access:

version: 5
cache:
  accessControl:
    anonymousLevel: "read"
    users:
      ci-user:
        password: "«salt-hash-string»"
        level: "readwrite"
        note: "Continuous Integration User"

Prior to v6.0 of the remote cache node in schema v1, passwords were stored in plain text in the configuration file. When the node starts, it will convert v1 configuration files to v2 to hash the credentials. If you’re writing a v1 configuration file, the above would look like this:

version: 1
cache:
  credentials:
    anonymousLevel: "READ"
    users:
      - username: "ci-user"
        password: "my-password"
        level: "READWRITE"
        note: "Continuous Integration User"

User interface access control

Access to the build cache node’s configuration UI can be configured in the following ways:

  • Generated (default) - a required username and password are uniquely generated and printed to the console each startup.

  • Secure - a provided username and password are required.

  • Open - access is allowed without any credentials.

  • Disabled - no access is allowed (configuration changes must be made via file or via Develocity).

Using the Open access type allows unrestricted access to the build cache node UI and may allow anyone to change the cache node configuration, including the Cache access control settings. It is strongly recommended to only enable unrestricted UI access when you are using the build cache node on a secured network.
Changes to the configuration user interface access mode take effect after the build cache node is restarted.

Configuring via the UI

Access to the build cache node’s configuration user interface access can be configured via the configuration user interface itself. It is available on the build cache node homepage under the Build cache node UI section.

Configuring via the CLI

UI access can be configured from the command line using the ui-access subcommand.

java -jar build-cache-node-20.0.jar ui-access «access-mode»
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access «access-mode»

Build cache nodes store their configuration on the filesystem. When nodes are started, this location is specified with either --data-dir or --config-dir. Be sure to use the same config location with the ui-access subcommands as you use when starting the build cache node. If you are running the build cache node using Docker, be sure to specify the same data volume when running the ui-access subcommands.

Viewing the current UI access type

To see the current UI access mode, run the ui-access status command:

java -jar build-cache-node-20.0.jar ui-access status
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access status
Disabling UI access

To completely disable the configuration UI, run:

java -jar build-cache-node-20.0.jar ui-access disabled
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access disabled
Allowing unrestricted UI access
Using the Open access type allows unrestricted access to the build cache node UI and may allow anyone to change the cache node configuration, including the Cache access control settings. It is strongly recommended to only enable unrestricted UI access when you are using the build cache node on a secured network.

To allow anyone to access the configuration user interface without authentication, run:

java -jar build-cache-node-20.0.jar ui-access open
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access open
Restricting UI access using a specific username and password

To restrict access to the configuration UI using a username and password, run:

java -jar build-cache-node-20.0.jar ui-access secure -username «username»
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access secure -username «username»

You will be prompted for the password.

Use the --password <password-file> command-line argument to specify the password non-interactively (where <password-file> is the path to a file that contains the password to use). To specify the password via standard input, specify - as the password file. You can then pipe the required password to the command:

echo "$PASSWORD_ENV_VAR" | java -jar path/to/build-cache-node-20.0.jar ui-access secure --username «username» --password - 2>/dev/null
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access secure --username «username» --password - 2>/dev/null
Piping the password using echo like shown above will leak the password into your shell’s command history. It is more secure to use --password <password-file> with a regular file.
Restricting UI access using a generated username and password

To restrict access to the configuration UI using a generated username and password, run:

java -jar build-cache-node-20.0.jar ui-access generated
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:20.0 \
   ui-access generated

Configuring via the configuration file

Access to the build cache node’s configuration user interface can be specified in the configuration file.

Disabling UI access

Set the uiAccess.type property to "disabled" to disable the configuration UI so that no one can access it:

version: 5
uiAccess:
  type: "disabled"
Allowing unrestricted UI access
Using the Open access type allows unrestricted access to the build cache node UI and may allow anyone to change the cache node configuration, including the Cache access control settings. It is strongly recommended to only enable unrestricted UI access when you are using the build cache node on a secured network.

Set the uiAccess.type property to "open" to allow anyone to access the configuration UI without authentication:

version: 5
uiAccess:
  type: "open"
Restricting UI access using a specific username and password

Set the uiAccess.type property to "secure" to restrict access using a specific username and password. You will also have to provide the username and the hash of the password. Use the hash subcommand to generate the password hash. See the “Generating password hashes” section for details.

version: 5
uiAccess:
  type: "secure"
  username: "myChosenUsername"
  password: "«salt-hash-string»"

Prior to v4.2 of the remote cache node, to secure the UI, you can create a file at «data-dir»/conf/credentials.txt with the desired username and password on separate lines, as per the following example:

myChosenUsername
sdlfjhpos6lnFLRJGFLAE
Restricting UI access using a generated username and password

Set the uiAccess.type property to "generated" to restrict access using a generated username and password. The generated username and password is printed to the console when the build cache node is restarted.

version: 5
uiAccess:
  type: "generated"

Insecure configuration

The build cache node is considered insecure if any of the following are true:

  • Anonymous users are allowed to access the configuration UI.

  • Anonymous users are allowed to write to the build cache.

When a build cache node is insecure, anyone could write malicious cache entries, which could put your organization at great risk. For this reason, when the build cache node is insecure, warnings are displayed on the console, in the configuration UI, and on the Build cache network health page of Develocity (when the build cache node is signed-in to Develocity).

You can secure the build cache node by:

  1. Changing the node to use the Secured UI Access Type. See the “User interface access control” section for details on how to change the access type.

  2. Changing the anonymous cache access to Read or None. See the “Cache access control” section for details.

If you understand the risks, and your use-case requires you to run with an insecure configuration, then you can suppress the warnings by passing the --no-warn-anon-cache-write and the --no-warn-anon-ui-access flags to the build cache node’s start command. Use --no-warn-anon-cache-write to suppress warnings about anonymous write access to the build cache. Use --no-warn-anon-ui-access to suppress warnings about anonymous access to the configuration UI.

java -jar build-cache-node-20.0.jar start --no-warn-anon-cache-write --no-warn-anon-ui-access
docker run --detach \
   --user $UID \
   --volume /opt/build-cache-node:/data \
   --publish 80:5071 \
   --publish 6011:6011 \
   gradle/build-cache-node:20.0 \
   start --no-warn-anon-cache-write --no-warn-anon-ui-access

Increasing memory limits

By default, the build cache node uses 1 GiB of heap memory and 500MiB of off heap memory. If you need to allocate more memory, the application can be configured as follows:

JAR

The value for heap and off heap memory is set using the standard JDK parameters when running the JAR.

java -jar build-cache-node-20.0.jar -Xms3g -Xmx3g -XX:MaxDirectMemorySize=1g start

Docker

The value for heap and off heap memory is set using an environment variable called JAVA_OPTS in the docker run instruction.

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 80:5071 \
    --publish 6011:6011 \
    --env JAVA_OPTS="-Xms3g -Xmx3g -XX:MaxDirectMemorySize=1g" \
    gradle/build-cache-node:20.0 \
    start

Kubernetes

The value for heap and off heap memory is set using an environment variable called JAVA_OPTS for the container in the Kubernetes manifest. It is important that the container resources are also adjusted accordingly.

containers:
- name: build-cache-node
  args: [ "start" ]
  env:
  - name: JAVA_OPTS
    value: "-Xms3g -Xmx3g -XX:MaxDirectMemorySize=1g"
  resources:
    requests:
      memory: 3Gi
    limits:
      memory: 5Gi

Using HTTPS

By default, the build cache node serves over HTTP. Using HTTPS requires extra configuration.

Using your own certificate

To use your own certificate, place an X.509 certificate (including intermediates) at «data-dir»/conf/ssl.crt and your PKCS#1 or PKCS#8 private key at «data-dir»/conf/ssl.key. Both files must be in PEM format.

Using a generated certificate

This feature requires version 4.3 or later of the cache node.

You can have the server generate its own self-signed certificate to use. To do this, specify the --generate-self-signed-cert argument to the node application.

java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --port 443 --generate-self-signed-cert

Or when using the Docker image:

docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 443:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start --generate-self-signed-cert

This certificate will not be trusted by clients, and will require extra configuration by clients.

Please consult the Gradle user manual or Develocity Maven Extension User Manual for how to configure Gradle or Maven builds to accept an untrusted SSL connection.

If you are connecting the node with other cache nodes (i.e. for replication), you will need to configure those nodes to allow untrusted SSL connections, for which how to do so is described in the next section.

Allowing untrusted SSL connections

This feature requires version 4.3 or later of the cache node.

Build cache node

By default, the cache node will not allow connections to Develocity or other cache nodes if they serve over HTTPS and present untrusted certificates (e.g. self-signed). In order to allow such connections, the cache node must be started with the --allow-untrusted-ssl argument, as follows:

JAR
java -jar build-cache-node-20.0.jar start --data-dir /opt/build-cache-node --port 443 --allow-untrusted-ssl
Docker
docker run --detach \
    --user $UID \
    --volume /opt/build-cache-node:/data \
    --publish 443:5071 \
    --publish 6011:6011 \
    gradle/build-cache-node:20.0 \
    start --allow-untrusted-ssl
Kubernetes
containers:
- name: build-cache-node
  args:
  - start
  - "--allow-untrusted-ssl"

Develocity

If your cache node is using an untrusted certificate, and you are connecting it with Develocity, you will need to configure it to allow untrusted SSL communication with cache nodes.

This can be done by enabling in the Develocity admin console settings page, by checking the Allow untrusted SSL communication with cache nodes checkbox in the networking settings section.

Importing additional trusted SSL certificates

This feature requires version 9.8 or later of the cache node.

By default, the build cache node uses the default trust settings of the Java runtime that it runs with when connecting to Develocity or other build cache nodes using SSL. If your organization uses certificates that are not signed by a trusted certificate authority, you must perform additional configuration for this to work. This may be the case if you use self-signed certificates or an internal certificate authority.

Any additional certificates to trust must be added to a single PEM file. The application can then be configured as follows:

JAR

Additional certificates are configured using the standard keytool utility of your JDK distribution prior to running the build cache.

Docker

The PEM file needs to be created as «data-dir»/conf/trusted-ssl.crt, the certificates are installed during container startup.

Kubernetes

The contents of the PEM file must be created as a secret called trusted-ssl, under the key trusted-ssl.crt.

kubectl create secret generic trusted-ssl --from-file=trusted-ssl.crt

The trusted-ssl secret is mounted as a volume to the build cache node at the path /data/conf/trusted-ssl.crt

spec:
  template:
    spec:
      containers:
      - name: build-cache-node
        args: [ "start" ]
        volumeMounts:
        - mountPath: /data/conf/trusted-ssl.crt
          name: trusted-ssl
          subPath: trusted-ssl.crt
          readOnly: true
      volumes:
      - name: trusted-ssl
        secret:
          secretName: trusted-ssl

Gradle usage

In order to use a build cache, the address of the build cache needs to be configured in your Gradle builds.

Groovy
buildCache {
    remote(HttpBuildCache) {
        url = 'https://buildcache.mycompany.com/cache/'
    }
}
Kotlin
buildCache {
    remote(HttpBuildCache::class) {
        url = uri("https://buildcache.mycompany.com/cache/")
    }
}

Develocity Gradle Plugin version 3.11 and above provides a build cache connector that can simplify connecting to the Develocity built-in build cache. Please consult the build cache connector documentation to configure it for your build.

For information about using the build cache from Gradle, please consult the Gradle user manual.

Apache Maven™ usage

To use a Build Cache, the address of the Build Cache needs to be configured in the configuration for your Maven builds, unless you are connecting to the built-in cache node of Develocity.

develocity.xml
<develocity>
  <server>
    <url>https://develocity.mycompany.com</url>
  </server>
  <buildCache>
    <remote>
      <server>
        <url>https://buildcache.mycompany.com/cache/</url>
      </server>
    </remote>
  </buildCache>
</develocity>

For more information about using the build cache from Apache Maven™, consult the Develocity Maven Extension User Manual.

Bazel Usage

To use the Build Cache node as a Bazel remote cache, the address of the Build Cache needs to be configured via the CLI or (more conveniently) by adding the following lines to your .bazelrc file:

common:develocity --remote_cache=grpcs://buildcache.mycompany.com:6011/
common:develocity --bes_backend=grpcs://buildcache.mycompany.com:6011/

For more information about using the Bazel remote cache, please consult the Develocity Bazel Configuration Guide.

sbt usage

To use a Build Cache, the address of the Build Cache needs to be configured in your sbt builds, unless you are connecting to the built-in cache node of Develocity.

build.sbt
ThisBuild / develocityConfiguration ~= { previous =>
  previous
    .withServer(
      previous.server
        .withUrl(url("https://develocity.mycompany.com"))
    )
    .withBuildCache(
      previous.buildCache
        .withRemote(
          previous.buildCache.remote
            .withServer(
              previous.buildCache.remote.server
                .withUrl(url("https://buildcache.mycompany.com/cache/"))
            )
        )
    )
}

For more information about using the build cache from sbt, consult the Develocity sbt Plugin User Manual.

Appendix A: Release history

20.0

19th August 2024
  • [NEW] Revised permission model that applies to all projects (when connected to Develocity with project-level access control enabled)

  • [FIX] Logging of access token signing key retrieval is noisy (when connected to Develocity)

19.2

4th September 2024
  • [NEW] Increase health check tolerance when target size is exceeded

19.1

4th July 2024
  • [NEW] Improved cache eviction efficiency

  • [FIX] Resource leak at startup when namespaced cache entries are present

19.0

2nd April 2024
  • [NEW] Support for short-lived access tokens (when connected to Develocity)

  • [NEW] Build cache node JAR is compiled for and requires Java 21

  • [FIX] Bazel builds may cause shutdown when Build Cache node uses slower disks

18.1

23rd February 2024
  • [FIX] Cache entry eviction may fail to finish and cause 'out of disk' errors

18.0

5th December 2023
  • [NEW] Update JDK Docker base image to JDK 17.0.9

17.1

2nd October 2023
  • [NEW] System property to toggle cache event publication (when connected to Develocity)

  • [NEW] Capture AWS ELB trace identifier (X-Amzn-Trace-Id) header value

17.0

13th September 2023
  • [NEW] Project-level access control support (when connected to Develocity)

  • [FIX] Warnings caused by presence of IP addresses with ports in X-Forwarded-For HTTP header

  • [FIX] Misleading warning that Build Cache is effectively inaccessible when registered with Develocity

16.1

28th July 2023
  • [FIX] Idle HTTP client connections can cause cache entries to become inaccessible

16.0

19th July 2023
  • [NEW] Build cache node can be used as a remote store for Bazel builds (when connected to Develocity)

15.1

28th July 2023
  • [FIX] Idle HTTP client connections can cause cache entries to become inaccessible

15.0

11th April 2023
  • [NEW] Build cache node JAR is compiled for and requires Java 17

  • [NEW] Official Docker image includes JDK 17 instead of JDK 11

  • [NEW] Cache entries are managed more efficiently

  • [FIX] Replication of entries when available space is low can cause build cache node to run out of space

  • [FIX] Too-large cache writes are rejected

14.0

8th December 2022
  • [FIX] Build cache nodes with many files and slow disk are slow to start

  • [FIX] Publishing cache events is logged as a warning when not connected to Develocity

13.3

14th November 2022
  • [NEW] Update JDK Docker base image to JDK 11.0.17

  • [FIX] Cache entries that reference files that no longer exist on disk return an invalid response

  • [FIX] Stack overflow when a large enough number of cache entries need to be evicted to maintain space

  • [FIX] Noisy logging when HTTP client fails to complete SSL handshake

13.2

17th October 2022
  • [FIX] Noisy logging of connection status changes, when connected to something not Develocity

  • [FIX] Restarting the build cache node container when using additional trusted SSL certs fails

  • [FIX] Improved error handling during healthcheck

  • [FIX] All additional trusted SSL certs are removed on restart before new certs are imported

13.1

24th August 2022
  • [NEW] Update JDK Docker base image to JDK 11.0.16.1

13.0

10th August 2022
  • [NEW] Support for access key based authentication

  • [NEW] Update JDK Docker base image to JDK 11.0.16

12.5

27th June 2022
  • [FIX] Match the Purge button’s label with the controller (it’s now Purge cache)

  • [FIX] Prevent weak ciphers from being used by the cache node for TLS

12.4

9th June 2022
  • [NEW] Optimized HTTPS support no longer depends on system OpenSSL

  • [NEW] Accept upper case characters in entry keys

  • [FIX] Maximum available mode (exclusive volume mode) also considers free space reported by the filesystem

12.3

19th May 2022
  • [FIX] Update JDK Docker base image to JDK 11.0.15 to mitigate ECDSA vulnerability

  • [FIX] The --path CLI argument is recognized once again

12.2

19th April 2022
  • [FIX] Reduce pointless log verbosity

12.1

21th March 2022
  • [FIX] Build cache node docker image uses Optimized SSL Mode

12.0

17th March 2022
  • [NEW] Make the free space buffer, effective target cache size, and maximum target cache size required

  • [NEW] Reserve disk space for incoming data

  • [NEW] Exclusive volume mode

  • [FIX] Generate helpful error messages for read-only config files

  • [FIX] Limit the max artifact size to the effective target cache size

11.2

3th February 2022
  • [FIX] Support Java 16

11.1

13th January 2022
  • [FIX] Free space buffer setting is retained on upgrade from v10.x

  • [FIX] Correctly resolve static assets of the Build Cache Node UI when the Build Cache Node is run on Windows

11.0

20th December 2021
  • [NEW] Add "Maximum available" target cache size configuration option

  • [NEW] Show the Develocity version the build cache node is connected to

  • [NEW] When maximum artifact size is greater than target cache size, maximum artifact size is automatically reduced and warnings are displayed

  • [FIX] The Build Cache Node Configuration UI no longer automatically refreshes text inputs

  • [FIX] Upgrade Log4j to 2.17.0

10.3

16th December 2021
  • [FIX] Update Alpine Docker base image to mitigate vulnerability for possible code execution

  • [FIX] Update Netty to mitigate vulnerability for "Inconsistent Interpretation of HTTP Requests"

10.2

15th December 2021

10.1

13th December 2021

10.0

15th September 2021
  • [NEW] Ensures a minimum amount of free space is always available by maintaining a free space buffer

  • [NEW] Sends startup warnings and total uptime to Develocity (when connected to a Develocity server)

  • [NEW] Optionally evicts entries by age (regardless of the build cache size)

  • [NEW] CLI subcommands for configuring the configuration user interface access control

  • [NEW] Configuration user interface support for configuring the UI access control

  • [NEW] Optionally generates a username and password to access the build cache node configuration user interface

  • [FIX] Anonymous build cache access is allowed by default (disable anonymous cache access by default instead)

  • [FIX] Anonymous configuration user interface access is allowed by default (instead generate a username and password on startup)

  • [FIX] Java illegal access warnings are emitted in log files and standard output

9.11

28th July 2021
  • [NEW] Added the --config-dir command line parameter, for specifying custom location of configuration directory

  • [FIX] Improved command-line usage help text

9.10

20th July 2021
  • [NEW] Added the start subcommand for starting the build cache node. Starting the build cache node without the start subcommand is deprecated

  • [NEW] Added the hash subcommand for generating password hashes and deprecated the --hash-password and --hash-password-stdin command line arguments

9.9

11th June 2021
  • [NEW] Password hashes can be generated non-interactively

  • [NEW] The application base path can be set using the new --path command line argument

9.8

1st June 2021
  • [NEW] Importing additional trusted SSL certificates

9.7

15th March 2021
  • [NEW] Passwords used for access control are subject to basic complexity requirements

9.6

5th February 2021
  • [FIX] Establishing replication with node with large catalog may cause out-of-memory error

9.5

17th December 2020
  • [FIX] Reduced memory usage

9.4

27th October 2020
  • [FIX] Cache Node UI state detects reconnection correctly

9.3

27th July 2020
  • [NEW] Support for TLS 1.3 HTTPS connections

  • [FIX] Removal of support for TLS 1.0 and 1.1 for HTTPS connections

9.2

10th June 2020
  • [FIX] Security improvements

9.1

4th May 2020
  • [FIX] Nodes send larger batches of cache events to Develocity if connected

  • [FIX] Nodes should not log excessively if very busy and not connected to Develocity

9.0

25th November 2019
  • [NEW] Build cache node JAR is compiled for and requires Java 11

  • [FIX] UI Login failure screen renders correctly

  • [FIX] Zero length submissions should be retained between restarts

  • [FIX] Duplicate headers are not sent during replication

8.1

24th September 2019
  • [FIX] Client errors such as 404 requests should not be logged to the application log

8.0

22th August 2019
  • [NEW] Dockerised cache node runs on Java 11

  • [NEW] Running remote build cache nodes can be replaced by another instance

  • [FIX] Failed build cache stores should not leave files in upload directory

7.1

29th July 2019
  • [FIX] Large cache entries cannot be downloaded from the Develocity user interface

7.0

1st March 2019
  • [NEW] Support for Maven builds with Develocity Maven Extension [requires Develocity]

  • [FIX] Cache credentials are not encrypted in transmission when set from Develocity

6.0

12th February 2019
  • [FIX] Browser content sniffing is not explicitly disabled

  • [FIX] Browser cross site scripting prevention is not enabled

  • [FIX] Rendering of node user interface in an iframe is not disabled

  • [FIX] Cache and user interface access credentials are not encrypted at rest

5.2

21st January 2019
  • [FIX] Cache access credentials are visible in the user interface

5.1

21st December 2018
  • [FIX] Concurrent on-demand replication requests cause redundant requests to the replication source

5.0

22nd August 2018
  • [NEW] Cache entries can be searched and downloaded across all nodes from Develocity

4.3

7th August 2018
  • [NEW] Run with --generate-self-signed-cert to serve HTTPS with a self-signed certificate

  • [NEW] Run with --allow-untrusted-ssl to allow communication with nodes and Develocity serving an untrusted certificate

4.2

12th June 2018
  • [NEW] Cache node is available as a single JAR file

  • [NEW] Cache configuration is stored in a YAML file instead of in a proprietary binary format

  • [NEW] Additional JVM options can be specified when running the docker container as the JAVA_OPTS env var

  • [NEW] Nodes can now serve HTTPS traffic without an extra proxy

  • [NEW] Logs are written to the data directory’s logs directory instead of stdout

4.1

16th April 2018
  • [FIX] Improved logging of Develocity connection problems

4.0

10th April 2018
  • [NEW] Cache items can be replicated preemptively

  • [NEW] Nodes report their health status to Develocity

3.2

12th February 2018
  • [NEW] Increased default cache size from 1GB to 10GB

3.1

9th January 2018
  • [FIX] Logging of communication between nodes and Develocity is missing data

  • [FIX] Nodes communicate with the Develocity built-in node via the Develocity public address, not their address for Develocity

  • [FIX] User cancelled build cache uploads are logged as errors

3.0

5th December 2017
  • [NEW] Nodes can replicate entries from other nodes or Develocity [requires Develocity]

2.0

18th October 2017
  • [NEW] An unlimited number of user/passwords can be used for cache access control

1.2

11th September 2017
  • [FIX] Node settings are not loaded on restart

1.1

24th August 2017
  • [FIX] Node may crash when updating the node settings via the user interface

1.0

20th June 2017
  • Initial release

Appendix B: Upgrade notes

Upgrading from Build Cache Node 9.9 or earlier

In version 9.10, the start and hash subcommands were introduced. Starting the build cache node without using the start subcommand is deprecated and support will be removed in a future release. Generating password hashes using the --hash-password and --hash-password-stdin arguments is also deprecated.

After upgrading to build cache node version 9.10 or higher, it is strongly recommended to adjust any startup automation (scripts, Kubernetes manifests, etc.) to use the start subcommand. The start subcommand has the same arguments that were passed to the build cache node executable (such as --data-dir) so you only need to add start before any other arguments.

You should also update any automation that currently uses the --hash-password or --hash-password-stdin command line arguments to use the hash subcommand instead.

Appendix C: JAR downloads

Support for build cache node versions older than 14.0 is ending. Discontinued versions of the build cache node will stop being distributed as of December 2024. Versions older than 14.0 will not be able to connect to Develocity 2024.3 and above.

Appendix D: Config schema downloads

Appendix E: Verifying the signature of the build cache node artifacts

(build cache node 9.2+, build cache node schema 3+)

The build cache node jar and schema are published to docs.gradle.com alongside its signatures. The public key is published to https://pool.sks-keyservers.net and https://keys.openpgp.org. You can verify the signature of the jar as follows:

$ curl -OL https://docs.gradle.com/build-cache-node/jar/build-cache-node-20.0.jar && \
  curl -OL https://docs.gradle.com/build-cache-node/jar/build-cache-node-20.0.jar.asc && \
  gpg --keyserver keys.openpgp.org --recv-key 7B79ADD11F8A779FE90FD3D0893A028475557671 && \
  gpg --verify build-cache-node-20.0.jar.asc build-cache-node-20.0.jar

Or verify the signature of the schema as follows:

$ curl -OL https://docs.gradle.com/build-cache-node/schema/build-cache-node-config-schema-5.json && \
  curl -OL https://docs.gradle.com/build-cache-node/schema/build-cache-node-config-schema-5.json.asc && \
  gpg --keyserver keys.openpgp.org --recv-key 7B79ADD11F8A779FE90FD3D0893A028475557671 && \
  gpg --verify build-cache-node-config-schema-5.json.asc build-cache-node-config-schema-5.json

The output of the last command should look similar to the following:

gpg: Signature made Thu Sep 28 16:17:46 2023 CEST
gpg:                using RSA key 893A028475557671
gpg: Good signature from "Gradle Inc. <info@gradle.com>" [unknown]
gpg:                 aka "Gradle Inc. <maven-publishing@gradle.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 7B79 ADD1 1F8A 779F E90F  D3D0 893A 0284 7555 7671

This verifies that the artifact was signed with the private key that corresponds to the imported public key. The warning is emitted because you haven’t explicitly trusted the imported key (hence [unknown]). One way of establishing trust is to verify the fingerprint over a secure channel. Please contact technical support should you wish to do so.