---
component: bcn
version: "21.2"
slug: bcn/index
canonical_url: "https://docs.gradle.com/develocity/bcn/21.2/"
title: "Develocity Build Cache Node User Manual"
description: "Explore the Develocity Build Cache node documentation to learn how to set up, configure, and optimize your Build Cache for faster and more efficient builds."
keywords:
  - "Build Cache"
  - "Kubernetes"
  - "installation"
  - "configuration"
status: current
---

> Canonical: <https://docs.gradle.com/develocity/bcn/21.2/>

<!-- llms-index: https://docs.gradle.com/develocity/llms.txt -->

<a id="component-eol-banner"></a>

The Develocity Build Cache Node has been [**deprecated**](https://gradle.com/develocity/releases/2025.2#deprecations) and will no longer be distributed, supported or available after **December 31, 2026**. Please migrate to [Develocity Edge](https://docs.gradle.com/develocity/edge/2.1/), which offers remote build caching and is designed for enhanced resiliency, scalability, and easier operation.

# Develocity Build Cache Node User Manual

<a id="preamble"></a>

Version: 21.2

The [Develocity Build Cache](https://gradle.com/develocity/product/build-cache/) accelerates build execution by storing and reusing reproducible task and goal outputs, eliminating redundant work across local and remote environments.

The Build Cache node is distributed as a [Docker](https://www.docker.com/) image via [Docker Hub](https://hub.docker.com/r/gradle/build-cache-node), and as a [executable JAR](https://docs.gradle.com/downloads/build-cache-node/build-cache-node-21.2.jar). Both distributions offer the same functionality.

<a id="requirements"></a>

## Requirements

<a id="data-directory-disk-usage"></a>

### 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 more than the cache size to store log files, config files and other operational files.

<a id="cpu-memory"></a>

### CPU & Memory

By default, the Build Cache node uses up to about 1.5 GiB of memory.

The Build Cache node doesn’t require significant CPU resources. Performance is generally constrained by network access to the Build Cache node.

<a id="installation"></a>

## Installation

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

<a id="jar"></a>

### JAR

[Download](https://docs.gradle.com/downloads/build-cache-node/build-cache-node-21.2.jar) version 21.2 of the JAR.

> [!NOTE]
> Older versions of the JAR can be found in the legacy documentation archive.

<a id="java-runtime"></a>

#### Java Runtime

Build Cache node and Java version overview  
| Build Cache node JAR | Java version |
| --- | --- |
| Version 19.0 and later | Java 21 |
| Version 15.0 till 18.0 | Java 17 |
| Version 14.0 | Java 11 |

<a id="running"></a>

#### Running

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

```shell
java -jar build-cache-node-21.2.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).

<a id="specifying-a-data-directory"></a>

#### Specifying a Data Directory

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

```shell
java -jar build-cache-node-21.2.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 isn’t supported.

> [!NOTE]
> To use the current directory as the data directory, use `--data-dir .`

<a id="specifying-a-configuration-directory"></a>

#### Specifying a Configuration Directory

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

```shell
java -jar build-cache-node-21.2.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).

> [!NOTE]
> `«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`.

<a id="providing_a_config_file"></a>

#### 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’s 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 won’t be written back to your config source.

> [!NOTE]
> `«config-dir»` is a placeholder referring to the Build Cache node’s configuration directory.

<a id="specifying-the-ports"></a>

#### 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:

```shell
java -jar build-cache-node-21.2.jar start --data-dir /opt/build-cache-node --port 443
```

> [!NOTE]
> Most systems require superuser 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»`:

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

<a id="specifying_the_application_base_path"></a>

#### 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:

```shell
java -jar build-cache-node-21.2.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/.

<a id="optimized-https"></a>

#### Optimized HTTPS

The Build Cache serves HTTPS traffic more efficiently on some platforms. If HTTPS is configured but optimized HTTPS support couldn’t be loaded, the application will emit a warning to the console of:

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

Optimized HTTPS support is available on the following platforms:

*   Linux (x86\_64)
    
*   macOS (aarch\_64/x86\_64)
    
*   Windows (x86\_64)
    

<a id="auto-start"></a>

#### 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](https://www.freedesktop.org/wiki/Software/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:

```shell
#!/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-21.2.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:

```ini
[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:

```shell
systemctl start gradle-remote-build-cache
```

4\. Run the following to have systemd start the Build Cache node on system boot:

```shell
systemctl enable gradle-remote-build-cache
```

<a id="docker"></a>

### Docker

<a id="installation-2"></a>

#### Installation

With Docker installed, starting a Build Cache node is as simple as the following command:

```shell
docker run --detach \
  --user $UID \
  --volume /opt/build-cache-node:/data \
  --publish 80:5071 \
  --publish 6011:6011 \
  gradle/build-cache-node:21.2 \
  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.

<a id="airgapped-installation"></a>

#### Airgapped Installation

To install the Docker Build Cache node on a host that isn’t connected to the Internet (for example, 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
    
    ```shell
    docker pull gradle/build-cache-node:21.2
    ```
    
2.  Export the image to a file
    
    ```shell
    docker save gradle/build-cache-node:21.2 --output build-cache-node.tar
    ```
    
3.  Copy this file across to the airgapped host, and then import the image into Docker
    
    ```shell
    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:

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

<a id="versioning"></a>

#### Versioning

It’s 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 isn’t 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](https://docs.gradle.com/develocity/2026.1/miscellaneous/compatibility/).

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.

> [!WARNING]
> Support for Build Cache node versions older than 14.0 has ended. Discontinued versions of the Build Cache node will stop being distributed as of December 2024. Versions older than 14.0 won’t be able to connect to Develocity 2024.3 and above.

<a id="binding-the-data-directory"></a>

#### 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:

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

> [!WARNING]
> 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 isn’t 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.

> [!NOTE]
> For more information on managing data volumes with Docker, see [this tutorial](https://docs.docker.com/engine/storage/volumes/).

<a id="run-as-user"></a>

#### Run-as User

The Build Cache node Docker image doesn’t 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’s 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 want 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:

```shell
docker run --detach \
  --user 5000 \
  --volume /opt/build-cache-node:/data \
  --publish 80:5071 \
  --publish 6011:6011 \
  gradle/build-cache-node:21.2 \
  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.

<a id="port-mapping"></a>

#### 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’s 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:

```shell
docker run --detach \
  --user $UID \
  --volume /opt/build-cache-node:/data \
  --publish 8443:5071 \
  --publish 6011:6011 \
  gradle/build-cache-node:21.2 \
  start
```

> [!NOTE]
> If you aren’t using Bazel and don’t want to expose its port, you can remove it from the mappings, effectively "hiding" it.

<a id="specifying_the_application_base_path_2"></a>

#### 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:

```shell
docker run --detach \
  --user $UID \
  --volume /opt/build-cache-node:/data \
  --publish 8443:5071 \
  --publish 6011:6011 \
  gradle/build-cache-node:21.2 \
  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/.

<a id="auto-start-2"></a>

#### Auto Start

The Build Cache node container can be automatically restarted on system boot by leveraging Docker’s [restart policies](https://docs.docker.com/reference/cli/docker/container/run/#restart). Starting a Build Cache node container with `--restart always` will ensure that it’s always running unless explicitly stopped.

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

<a id="kubernetes"></a>

### 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](#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.

**Example Kubernetes manifest for deploying a Build Cache node:**

```
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:21.2
        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
```

> [!NOTE]
> 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](#exclusive_volume) section.

<a id="providing-a-config-file-from-a-secret"></a>

#### 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 discussion](https://github.com/kubernetes/kubernetes/issues/62099)).

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]
> Note that this approach, makes the config file immutable and changes made through the UI or Develocity won’t be reflected in your secret. See the [”Providing a Config File” section](#providing_a_config_file) for more details.

<a id="creating-the-secret"></a>

##### 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:

```shell
kubectl -n <remote-bcn-ns> create secret generic gradle-build-cache-config-secret --from-file=config.yaml
```

**Example config file for creating the secret:**

```
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
```

> [!NOTE]
> Any changes to the config file require recreating the secret and restarting the Build Cache Pod.

<a id="updating-the-manifest"></a>

##### Updating the Manifest

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

**Example Kubernetes manifests snippet for loading config from a 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:21.2
        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
```

<a id="non-root-user"></a>

#### Non-Root User

By default, the Build Cache node application will run as the root user. It’s possible to run as a non-root user by including a [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) in the deployment manifest.

```yaml
securityContext:
  runAsUser: 999
  runAsGroup: 0
  fsGroup: 0
```

<a id="exposing-the-build-cache-node-outside-your-cluster"></a>

#### Exposing the Build Cache Node Outside Your Cluster

The sample Kubernetes manifest includes a [service](https://kubernetes.io/docs/concepts/services-networking/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 isn’t accessible outside of the Kubernetes cluster by default. To access the Build Cache node outside 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:

**Example Kubernetes Ingress for exposing the Build Cache node:**

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: build-cache-node-ingress
spec:
  tls:
  - hosts:
    - YOUR_DOMAIN_NAME
    secretName: YOUR_TLS_SECRET_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
```

<a id="exclusive_volume"></a>

### 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’s _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.

```shell
java -jar build-cache-node-21.2.jar start --data-dir /opt/build-cache-node --use-exclusive-volume-with-size 10Gi
```

```shell
EXCLUSIVE_VOLUME_SIZE=10Gi java -jar build-cache-node-21.2.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](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-units-in-kubernetes) notation.

<a id="post-installation-setup"></a>

## Post-installation setup

<a id="configure-ui-access-control"></a>

### Configure UI Access Control

By default, access to the configuration user interface requires a generated username and password that’s printed to the console on startup. It’s recommended to change this to a username and password that you specify. See the [“User interface access control” section](#user_interface_access_control) for details.

<a id="enable-cache-access"></a>

### 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](#cache_access_control) for details.

<a id="verify-connectivity"></a>

### Verify Connectivity

The Build Cache node has a `/ping` HTTP endpoint to test connectivity, which can be used to test if it’s 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:

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

It should return `SUCCESS`.

<a id="disk-space-management"></a>

### 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](#cache_settings) for more details on changing the disk space management settings.

<a id="purging-the-cache"></a>

#### Purging the Cache

All 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.

<a id="logging"></a>

### 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`).

<a id="disaster-recovery"></a>

### 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.

> [!NOTE]
> 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 doesn’t need to be backed up separately.

<a id="configuration"></a>

## Configuration

The cache settings and Develocity connection settings can be configured via the Build Cache node’s web interface. 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](#providing_a_config_file) for details.

> [!NOTE]
> 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.

<a id="accessing-the-configuration-user-interface"></a>

### 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 in to the configuration UI for the first time. See the [“User interface access control” section](#user_interface_access_control) for details on how to change the UI access control.

> [!NOTE]
> 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](#specifying_the_application_base_path) or [“Specifying the application base path” section when running via Docker](#specifying_the_application_base_path_2) for details on setting the application path.

<a id="editing-the-file"></a>

### Editing the File

The config file is stored at `«data-dir»/conf/config.yaml`, and is in YAML format. It’s 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 21.2 uses schema version 5. This schema is published in [JSON schema](https://json-schema.org/) format, and is available [here](https://docs.gradle.com/downloads/build-cache-node-config-schema/build-cache-node-config-schema-5.json).

The config file should always start with the schema version:

```yaml
version: 5
```

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

```yaml
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.

<a id="generating_password_hashes"></a>

#### 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.

<a id="tabs-1"></a>

*   <a id="tabs-1-shell"></a>
    
    Shell
    
*   <a id="tabs-1-docker"></a>
    
    Docker
    

<a id="tabs-1-shell--panel"></a>

```shell
java -jar path/to/build-cache-node-21.2.jar hash
Enter password:
Confirm password:
"7a+lG8aaYRGJCgDtsSrYcufys67tW1I/augaLUiN8As=:+Zv1/r2oY0T2anrooV8XVe6ovlCqBfOf2ZwgfoLA6Ew="
```

<a id="tabs-1-docker--panel"></a>

```shell
docker run --interactive --tty gradle/build-cache-node:21.2 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:

<a id="tabs-2"></a>

*   <a id="tabs-2-shell"></a>
    
    Shell
    
*   <a id="tabs-2-docker"></a>
    
    Docker
    

<a id="tabs-2-shell--panel"></a>

```shell
echo "$PASSWORD_ENV_VAR" | java -jar path/to/build-cache-node-21.2.jar hash --password -
"D3dyflAOczSzlnbKTyGaG8h8HU1wcU5kUH5/h7eySKY=:3QfbpLm5m6gvYBOY3kDbDMPuxpvKAj9ptaBPtDYDSy8="
```

<a id="tabs-2-docker--panel"></a>

```shell
echo "$PASSWORD_ENV_VAR" | docker run --interactive gradle/build-cache-node:21.2 hash --password -
"D3dyflAOczSzlnbKTyGaG8h8HU1wcU5kUH5/h7eySKY=:3QfbpLm5m6gvYBOY3kDbDMPuxpvKAj9ptaBPtDYDSy8="
```

> [!WARNING]
> Piping the password using echo like shown above will leak the password into your shell’s command history. It’s more secure to use `--password <password-file>` with a regular file.

<a id="develocity_registration"></a>

### 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](https://docs.gradle.com/develocity/2026.1/administration/build-acceleration/build-cache/#manual_build_cache_node_registration).

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

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

<a id="cache_settings"></a>

### Cache Settings

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

<a id="target_cache_size"></a>

#### 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’s 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:

```yaml
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](#free_space_buffer_size).

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:

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

<a id="free_space_buffer_size"></a>

#### Free Space Buffer Size

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:

```yaml
version: 5
cache:
  freeSpaceBufferSize: 2000
```

<a id="maximum_artifact_size"></a>

#### 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 want to cache.

Increasing this value may require further configuration changes in network components in your system (for example, 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:

```yaml
version: 5
cache:
  maxArtifactSize: 200
```

<a id="maximum_entry_age"></a>

#### 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](#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:

```yaml
version: 5
cache:
  maxEntryAgeInHours: 24
```

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

```yaml
version: 5
cache:
  maxEntryAgeInHours: null
```

<a id="overview-of-default-cache-size-settings"></a>

#### Overview of Default Cache Size Settings

The Build Cache node is configured with the following defaults:

*   [Target cache size](#target_cache_size) of 10 GiB.
    
*   [Free space buffer size](#free_space_buffer_size) of 1 GiB (how much free disk space to ensure is available at all times, reducing cache size if necessary).
    
*   [Maximum artifact size](#maximum_artifact_size) of 100 MiB (the largest cache artifact to accept).
    
*   No limit on [cache entry age](#maximum_entry_age).
    

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.

<a id="cache_access_control"></a>

#### 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’s 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.

> [!WARNING]
> When the anonymous access level is set to **Read and Write**, writing to the Build Cache doesn’t require credentials which may allow anyone to write malicious cache entries. It’s 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](https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_configure) or the [Develocity Maven Extension User Manual](https://docs.gradle.com/develocity/maven/2.4/maven-extension/) for details on how to specify credentials to use when accessing a cache.

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` isn’t 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](#generating_password_hashes) 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:

```yaml
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:

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

<a id="user_interface_access_control"></a>

### 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).
    

> [!WARNING]
> 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](#cache_access_control). It’s strongly recommended to only enable unrestricted UI access when you are using the Build Cache node on a secured network.

> [!NOTE]
> Changes to the configuration user interface access mode take effect after the Build Cache node is restarted.

<a id="configuring-via-the-ui"></a>

#### 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.

<a id="configuring-via-the-cli"></a>

#### Configuring via the CLI

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

<a id="tabs-3"></a>

*   <a id="tabs-3-shell"></a>
    
    Shell
    
*   <a id="tabs-3-docker"></a>
    
    Docker
    

<a id="tabs-3-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar ui-access «access-mode»
```

<a id="tabs-3-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  ui-access «access-mode»
```

> [!NOTE]
> 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.

<a id="viewing-the-current-ui-access-type"></a>

##### Viewing the Current UI Access Type

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

<a id="tabs-4"></a>

*   <a id="tabs-4-shell"></a>
    
    Shell
    
*   <a id="tabs-4-docker"></a>
    
    Docker
    

<a id="tabs-4-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar ui-access status
```

<a id="tabs-4-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  ui-access status
```

<a id="disabling-ui-access"></a>

##### Disabling UI Access

To disable the configuration UI, run:

<a id="tabs-5"></a>

*   <a id="tabs-5-shell"></a>
    
    Shell
    
*   <a id="tabs-5-docker"></a>
    
    Docker
    

<a id="tabs-5-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar ui-access disabled
```

<a id="tabs-5-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  ui-access disabled
```

<a id="allowing-unrestricted-ui-access"></a>

##### Allowing Unrestricted UI Access

> [!WARNING]
> 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](#cache_access_control). It’s 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:

<a id="tabs-6"></a>

*   <a id="tabs-6-shell"></a>
    
    Shell
    
*   <a id="tabs-6-docker"></a>
    
    Docker
    

<a id="tabs-6-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar ui-access open
```

<a id="tabs-6-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  ui-access open
```

<a id="restricting-ui-access-using-a-specific-username-and-password"></a>

##### Restricting UI Access Using a Specific Username and Password

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

<a id="tabs-7"></a>

*   <a id="tabs-7-shell"></a>
    
    Shell
    
*   <a id="tabs-7-docker"></a>
    
    Docker
    

<a id="tabs-7-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar ui-access secure -username «username»
```

<a id="tabs-7-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  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:

<a id="tabs-8"></a>

*   <a id="tabs-8-shell"></a>
    
    Shell
    
*   <a id="tabs-8-docker"></a>
    
    Docker
    

<a id="tabs-8-shell--panel"></a>

```shell
echo "$PASSWORD_ENV_VAR" | java -jar path/to/build-cache-node-21.2.jar ui-access secure --username «username» --password - 2>/dev/null
```

<a id="tabs-8-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  ui-access secure --username «username» --password - 2>/dev/null
```

> [!WARNING]
> Piping the password using echo like shown above will leak the password into your shell’s command history. It’s more secure to use `--password <password-file>` with a regular file.

<a id="restricting-ui-access-using-a-generated-username-and-password"></a>

##### Restricting UI Access Using a Generated Username and Password

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

<a id="tabs-9"></a>

*   <a id="tabs-9-shell"></a>
    
    Shell
    
*   <a id="tabs-9-docker"></a>
    
    Docker
    

<a id="tabs-9-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar ui-access generated
```

<a id="tabs-9-docker--panel"></a>

```shell
docker run \
  --interactive \
  --tty \
  --volume /opt/build-cache-node:/data \
  gradle/build-cache-node:21.2 \
  ui-access generated
```

<a id="configuring-via-the-configuration-file"></a>

#### Configuring via the Configuration File

Access to the Build Cache node’s configuration user interface can be specified in the configuration file.

<a id="disabling-ui-access-2"></a>

##### Disabling UI Access

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

```yaml
version: 5
uiAccess:
  type: "disabled"
```

<a id="allowing-unrestricted-ui-access-2"></a>

##### Allowing Unrestricted UI Access

> [!WARNING]
> 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](#cache_access_control). It’s 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:

```yaml
version: 5
uiAccess:
  type: "open"
```

<a id="restricting-ui-access-using-a-specific-username-and-password-2"></a>

##### 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](#generating_password_hashes) for details.

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

<a id="restricting-ui-access-using-a-generated-username-and-password-2"></a>

##### 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.

```yaml
version: 5
uiAccess:
  type: "generated"
```

<a id="insecure-configuration"></a>

### 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](#user_interface_access_control) 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](#cache_access_control) 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.

<a id="tabs-10"></a>

*   <a id="tabs-10-shell"></a>
    
    Shell
    
*   <a id="tabs-10-docker"></a>
    
    Docker
    

<a id="tabs-10-shell--panel"></a>

```shell
java -jar build-cache-node-21.2.jar start --no-warn-anon-cache-write --no-warn-anon-ui-access
```

<a id="tabs-10-docker--panel"></a>

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

<a id="increasing-memory-limits"></a>

## 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:

<a id="jar-2"></a>

### JAR

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

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

<a id="docker-2"></a>

### Docker

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

```shell
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:21.2 \
  start
```

<a id="kubernetes-2"></a>

### 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’s important that the container resources are also adjusted accordingly.

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

<a id="using-https"></a>

## Using HTTPS

By default, the Build Cache node serves over HTTP. Using HTTPS requires extra configuration.

<a id="using-your-own-certificate"></a>

### 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.

<a id="using-a-generated-certificate"></a>

### Using a Generated Certificate

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.

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

Or when using the Docker image:

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

This certificate won’t be trusted by clients, and will require extra configuration by clients.

Please consult the [Gradle user manual](https://docs.gradle.org/current/userguide/build_cache.html) or [Develocity Maven Extension User Manual](https://docs.gradle.com/develocity/maven/2.4/maven-extension/) 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.

<a id="allowing-untrusted-ssl-connections"></a>

### Allowing Untrusted SSL Connections

<a id="build-cache-node"></a>

#### Build Cache Node

By default, the cache node won’t 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:

<a id="jar-3"></a>

##### JAR

```shell
java -jar build-cache-node-21.2.jar start --data-dir /opt/build-cache-node --port 443 --allow-untrusted-ssl
```

<a id="docker-3"></a>

##### Docker

```shell
docker run --detach \
  --user $UID \
  --volume /opt/build-cache-node:/data \
  --publish 443:5071 \
  --publish 6011:6011 \
  gradle/build-cache-node:21.2 \
  start --allow-untrusted-ssl
```

<a id="kubernetes-3"></a>

##### Kubernetes

```yaml
containers:
  - name: build-cache-node
    args:
      - start
      - "--allow-untrusted-ssl"
```

<a id="develocity"></a>

#### 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.

<a id="importing-additional-trusted-ssl-certificates"></a>

### Importing Additional Trusted SSL Certificates

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 aren’t 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:

<a id="jar-4"></a>

#### JAR

Additional certificates are configured using the standard `keytool` utility of your JDK distribution prior to running the Build Cache.

<a id="docker-4"></a>

#### Docker

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

<a id="kubernetes-4"></a>

#### Kubernetes

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

```shell
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`

```yaml
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
```

<a id="gradle-usage"></a>

## Gradle usage

To use a Build Cache, the address of the Build Cache needs to be configured in your Gradle builds.

<a id="tabs-11"></a>

*   <a id="tabs-11-groovy"></a>
    
    Groovy
    
*   <a id="tabs-11-kotlin"></a>
    
    Kotlin
    

<a id="tabs-11-groovy--panel"></a>

```groovy
buildCache {
    remote(HttpBuildCache) {
        url = 'https://buildcache.example.com/cache/'
    }
}
```

<a id="tabs-11-kotlin--panel"></a>

```kotlin
buildCache {
    remote(HttpBuildCache::class) {
        url = uri("https://buildcache.example.com/cache/")
    }
}
```

> [!NOTE]
> The Develocity Gradle plugin 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, consult the [Gradle user manual](https://docs.gradle.org/current/userguide/build_cache.html).

<a id="apache_maven_usage"></a>

## 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.example.com</url>
  </server>
  <buildCache>
    <remote>
      <server>
        <url>https://buildcache.example.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](https://docs.gradle.com/develocity/maven/2.4/maven-extension/).

<a id="bazel_usage"></a>

## 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`](https://bazel.build/run/bazelrc) file:

```shell
common:develocity --remote_cache=grpcs://buildcache.example.com:6011/
common:develocity --bes_backend=grpcs://buildcache.example.com:6011/
```

For more information about using the Bazel remote cache, please consult the [Develocity Bazel Configuration Guide](https://docs.gradle.com/develocity/bazel/bazel-config/).

<a id="sbt_usage"></a>

## 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.example.com"))
    )
    .withBuildCache(
      previous.buildCache
        .withRemote(
          previous.buildCache.remote
            .withServer(
              previous.buildCache.remote.server
                .withUrl(url("https://buildcache.example.com/cache/"))
            )
        )
    )
}
```

For more information about using the Build Cache from sbt, consult the [Develocity sbt Plugin User Manual](https://docs.gradle.com/develocity/sbt/1.4/sbt-plugin/).

* * *

If you have any questions or need any assistance contact the Develocity support team or your customer success representative.

<a id="upgrade_notes"></a>

## Appendix A: Upgrade Notes

<a id="upgrading-from-build-cache-node-9-9-or-earlier"></a>

### 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’s 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.

<a id="jar_downloads"></a>

## Appendix B: JAR Downloads

> [!WARNING]
> Support for Build Cache node versions older than 14.0 has ended. Discontinued versions of the Build Cache node will stop being distributed as of December 2024. Versions older than 14.0 won’t be able to connect to Develocity 2024.3 and above.

> [!NOTE]
> Older versions of the JAR can be found in the legacy documentation archive.

*   [Build Cache node 21.2 JAR](https://docs.gradle.com/downloads/build-cache-node/build-cache-node-21.2.jar)
    
*   [Build Cache node 21.2 JAR SHA256](https://docs.gradle.com/downloads/build-cache-node/build-cache-node-21.2.jar.sha256)
    
*   [Build Cache node 21.2 JAR signature](https://docs.gradle.com/downloads/build-cache-node/build-cache-node-21.2.jar.asc)
    
*   [Build Cache node 21.2 JAR signature SHA256](https://docs.gradle.com/downloads/build-cache-node/build-cache-node-21.2.jar.asc.sha256)
    

<a id="schema_downloads"></a>

## Appendix C: Config Schema Downloads

> [!NOTE]
> Older versions of the config schema can be found in the legacy documentation archive.

*   [Build Cache node config schema 5](https://docs.gradle.com/downloads/build-cache-node-config-schema/build-cache-node-config-schema-5.json)
    
*   [Build Cache node config schema 5 SHA256](https://docs.gradle.com/downloads/build-cache-node-config-schema/build-cache-node-config-schema-5.json.sha256)
    
*   [Build Cache node config schema 5 signature](https://docs.gradle.com/downloads/build-cache-node-config-schema/build-cache-node-config-schema-5.json.asc)
    
*   [Build Cache node config schema 5 signature SHA256](https://docs.gradle.com/downloads/build-cache-node-config-schema/build-cache-node-config-schema-5.json.asc.sha256)
    

<a id="verifying-the-signature-of-the-build-cache-node-artifacts"></a>

## Appendix D: Verifying the Signature of the Build Cache Node Artifacts

_(Build Cache node 14.0+, Build Cache node schema 4+)_

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](https://pool.sks-keyservers.net) and [https://keys.openpgp.org](https://keys.openpgp.org). You can verify the signature of the JAR as follows:

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

Or verify the signature of the schema as follows:

```shell
curl -OL https://docs.gradle.com/downloads/build-cache-node-config-schema/build-cache-node-config-schema-5.json && \
curl -OL https://docs.gradle.com/downloads/build-cache-node-config-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: 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 (therefore `[unknown]`). One way of establishing trust is to verify the fingerprint over a secure channel. Please contact technical support should you want to do so.