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

Build cache nodes can optionally be connected with Gradle Enterprise for centralized management and monitoring, and to enable replicating cache entries between multiple nodes.

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

JAR

You can download version 10.0 of the JAR here.

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

Java runtime

Version 9.0 and later of the build cache node JAR require at least Java 11 to run. Older versions require at least 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-10.0.jar start

This will start the node with a data directory inside the $TEMP location and listening on port 5071.

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

Specifying the port

The default listening port is 5071.

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

java -jar build-cache-node-10.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.

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-10.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/, and the URL to use when configuring Gradle or Maven is https://localhost/my-path/cache/.

Optimized HTTPS

The build cache node can serve HTTPS traffic more efficiently if OpenSSL is installed on the host. If HTTPS is configured but a usable OpenSSL installation cannot be found, the application will emit a warning to the console of:

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

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 as superuser
java -jar /path/to/build-cache-node-10.0.jar start --data-dir /opt/build-cache-node --port 80

2. Create a file, /lib/systemd/system/gradle-remote-build-cache.service as root and make it executable, with the following contents:

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

[Service]
Restart=always
RestartSec=1
ExecStart=/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 \
    gradle/build-cache-node:10.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 port 80. 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:10.0
  2. Export the image to a file

    docker save gradle/build-cache-node:10.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 \
    gradle/build-cache-node:10.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 Gradle Enterprise installation that is not up to date as each major version of the build cache node has a minimum Gradle Enterprise version requirement. These minimum versions can be found in the Gradle Enterprise 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.

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 \
    gradle/build-cache-node:10.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 \
    gradle/build-cache-node:10.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 a single port 5071. This port must be mapped to a port on the host in order to expose it.

It is recommended to map this port to one of the standard HTTP ports 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 \
    gradle/build-cache-node:10.0 \
    start

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 \
    gradle/build-cache-node:10.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 \
    --restart always \
    gradle/build-cache-node:10.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.

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: gradle-enterprise
    component: build-cache-node
  ports:
  - name: build-cache-node
    port: 5071
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: build-cache-node
  labels:
    app: gradle-enterprise
    component: build-cache-node
spec:
  selector:
    matchLabels:
      app: gradle-enterprise
      component: build-cache-node
  serviceName: build-cache-node
  template:
    metadata:
      labels:
        app: gradle-enterprise
        component: build-cache-node
    spec:
      containers:
      - name: build-cache-node
        image: gradle/build-cache-node:10.0
        args: [ "start" ]
        ports:
        - containerPort: 5071
        resources:
          requests:
            memory: 1Gi
            cpu: 0.5
          limits:
            memory: 2Gi
            cpu: 1.5
        volumeMounts:
        - mountPath: /data
          name: build-cache-node-data-volume
  volumeClaimTemplates:
  - metadata:
      name: build-cache-node-data-volume
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: '10Gi'
      storageClassName: 'standard'

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/v1beta1
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: /
            backend:
              serviceName: build-cache-node
              servicePort: 5071

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.

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.

Configuration

The cache settings and Gradle Enterprise 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.

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

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 10.0 uses schema version 3. This schema is published in JSON schema format, and is available here.

The config file should always start with the schema version:

version: 3

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

version: 3
registration:
  serverAddress: "https://ge-hostname"
  nodeAddress: "https://node-hostname"
  key: "«key»"
  secret: "«secret»"
cache:
  targetSize: 50000
  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-10.0.jar hash
Enter password:
Confirm password:
"7a+lG8aaYRGJCgDtsSrYcufys67tW1I/augaLUiN8As=:+Zv1/r2oY0T2anrooV8XVe6ovlCqBfOf2ZwgfoLA6Ew="
> docker run --interactive --tty gradle/build-cache-node:10.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-10.0.jar hash --password -
"D3dyflAOczSzlnbKTyGaG8h8HU1wcU5kUH5/h7eySKY=:3QfbpLm5m6gvYBOY3kDbDMPuxpvKAj9ptaBPtDYDSy8="
> echo "$PASSWORD_ENV_VAR" | docker run --interactive gradle/build-cache-node:10.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.

Gradle Enterprise registration

Build cache nodes can be registered and connected with a Gradle Enterprise 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 Gradle Enterprise in order to obtain a key and secret for the node. Details on this process can be found in the Gradle Enterprise Admin Manual.

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

version: 3
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.

The 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: 3
cache:
  targetSize: 50000

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). Setting the value to 0 (zero) disables the free space buffer.

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

version: 3
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.

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

version: 3
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.

version: 3
cache:
  maxEntryAgeInHours: 24

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

version: 3
cache:
  maxEntryAgeInHours: null

Cache access control

Access to the build cache can be restricted. 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 Gradle Enterprise 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: 3
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: 3
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 Gradle Enterprise).

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-10.0.jar ui-access «access-mode»
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.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-10.0.jar ui-access status
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.0 \
   ui-access status
Disabling UI access

To completely disable the configuration UI, run:

java -jar build-cache-node-10.0.jar ui-access disabled
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.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-10.0.jar ui-access open
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.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-10.0.jar ui-access secured -username «username»
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.0 \
   ui-access secured -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-10.0.jar ui-access secured --username «username» --password - 2>/dev/null
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.0 \
   ui-access secured --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-10.0.jar ui-access generated
docker run \
   --interactive \
   --tty \
   --volume /opt/build-cache-node:/data \
   gradle/build-cache-node:10.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: 3
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: 3
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: 3
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: 3
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 Gradle Enterprise (when the build cache node is signed-in to Gradle Enterprise).

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-10.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 \
   gradle/build-cache-node:10.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-10.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 \
    --env JAVA_OPTS="-Xms3g -Xmx3g -XX:MaxDirectMemorySize=1g" \
    gradle/build-cache-node:{latest-build-cache-node-version} \
    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-10.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 \
    gradle/build-cache-node:10.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 Gradle Enterprise 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 Gradle Enterprise 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-10.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 \
    gradle/build-cache-node:10.0 \
    start --allow-untrusted-ssl
Kubernetes
containers:
- name: build-cache-node
  args:
  - start
  - "--allow-untrusted-ssl"

Gradle Enterprise

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

This can be done by enabling in the Gradle Enterprise 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 Gradle Enterprise 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 secert 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://gradle-build-cache.mycompany.com/cache/'
    }
}
Kotlin
buildCache {
    remote(HttpBuildCache::class) {
        url = uri("https://gradle-build-cache.mycompany.com/cache/")
    }
}

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

Apache Maven™ usage

In order 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 Gradle Enterprise.

gradle-enterprise.xml
<gradleEnterprise>
  <server>
    <url>https://gradle-enterprise.mycompany.com</url>
  </server>
  <buildCache>
    <remote>
      <server>
        <url>https://my-cache/cache/</url>
      </server>
    </remote>
  </buildCache>
</gradleEnterprise>

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

Appendix A: Release history

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 Gradle Enterprise (when connected to a Gradle Enterprise 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 Gradle Enterprise if connected

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

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 Gradle Enterprise user interface

7.0

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

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

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 Gradle Enterprise

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 Gradle Enterprise 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 Gradle Enterprise connection problems

4.0

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

  • [NEW] Nodes report their health status to Gradle Enterprise

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 Gradle Enterprise is missing data

  • [FIX] Nodes communicate with the Gradle Enterpise built-in node via the Gradle Enteprise public address, not their address for Gradle Enterprise

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

3.0

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

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

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-10.0.jar
curl -OL https://docs.gradle.com/build-cache-node/jar/build-cache-node-10.0.jar.asc
gpg --keyserver keys.openpgp.org --recv-key 314FE82E5A4C5377BCA2EDEC5208812E1E4A6DB0
gpg --verify build-cache-node-10.0.jar.asc build-cache-node-10.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-3.json
curl -OL https://docs.gradle.com/build-cache-node/schema/build-cache-node-config-schema-3.json.asc
gpg --keyserver keys.openpgp.org --recv-key 314FE82E5A4C5377BCA2EDEC5208812E1E4A6DB0
gpg --verify build-cache-node-config-schema-3.json.asc build-cache-node-config-schema-3.json

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

gpg: Signature made Tue May  5 08:36:01 2020 UTC
gpg:                using RSA key 5208812E1E4A6DB0
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: 314F E82E 5A4C 5377 BCA2  EDEC 5208 812E 1E4A 6DB0

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.