Version 2024.1

Develocity is a Kubernetes-based application, distributed as a Helm chart. Helm is a package manager for Kubernetes applications.

Helm manages all Develocity components.

Helm Overview

To use Helm, users must first import a Helm chart. A Helm chart is a Kubernetes manifest template, with variables that can be provided at installation time.

Providing Configuration to Helm

Helm uses a values.yaml file to populate these variables and generate the Kubernetes manifests.

The variables in values.yaml configure the Develocity installation with information such as networking, database, or hostname settings.

Here is a sample values.yaml file:

values.yaml
global:
  hostname: develocity.example.com
database:
  type: embedded
ingress:
  enabled: true

Helm configuration can be provided in several ways:

  • Passing values directly to the helm command using --set or --set-file.

  • Creating a Helm values file and passing it to helm using --values.

  • Editing the default Helm values file in the chart prior to running helm.

Once your values.yaml file is complete, you will install Develocity using a command similar to the one below:

helm install --values ./values.yaml
Unless otherwise indicated, most values are optional and have usable defaults.

Example Helm Values File

A complete example of the values file can be found here.

Considerations

Each section below contains an overview of Develocity installation options and their corresponding values.yaml variables:

  1. Global Options (Hostname, License)

  2. Horizontal Scaling Options

  3. Database Type (Embedded or External)

  4. Storage Settings

  5. Routing Options (Ingress, NodePort, LoadBalancer, OpenShift)

  6. Networking Options (Ports, Proxies, SSL)

  7. Object Storage

  8. Unattended Configuration

  9. Using an external Bazel cache

For installations on hosts with limited to no network connectivity, see the additional section:

  1. Airgap Installation

By the end of this guide, you will have a complete values.yaml file, ready for your Develocity installation with storage, networking, database settings, and more.

Helm Options

1. Global Options

Hostname

When installing Develocity, you will need to provide a hostname such as develocity.example.com.

This should be the hostname that users of the installation use to access it and therefore should resolve within your network. It is usually the name of the Develocity host or the hostname of a reverse proxy if one is being used.

Develocity will only accept requests with this hostname in their Host header.

A hostname for the application is supplied in the Helm values file as follows:

values.yaml
global:
  hostname: develocity.example.com

License

You have been provided with a Develocity license file called develocity.license.

This file can be used in any testing, staging or production deployments of Develocity.

Only the "data" portion of the license is needed in the Helm value file, but it is acceptable to include the entire license file contents:

values.yaml
global:
  license:
    file: R0VMRgF4nBWOSZKCMAAAX+QUu3BUIJAIwUQiwsViEwMIDKOyvH701n3p6nJBYxoRHnAUnwHwKLjb...
The license file can also be supplied as a helm argument using --set-file.

It is also possible to specify the license file as a Kubernetes secret. This can then be managed manually, or by tooling such as Sealed Secrets or AWS Secrets Manager.

To manually create a secret with the Develocity license:

$ kubectl create secret generic my-example-license-secret --from-file=license=path/to/develocity.license

Then configure Helm with the name of the secret:

values.yaml
global:
  license:
    secretName: my-example-license-secret

When specifying the license as a secret, an image pull secret must also be specified.

If performing an airgap installation, an image pull secret must be supplied anyway if the internal registry requires authentication.

If performing an online installation, the license file also needs to be created as an image pull secret:

$ kubectl create secret docker-registry my-example-license-image-pull-secret \
    --docker-username=ignored \
    "--docker-password=$(cat ./enterprise/internal-installs/develocity.license)" \
    --docker-server=registry.gradle.com
values.yaml
global:
  image:
    imagePullSecret: my-example-license-image-pull-secret

2. Horizontal Scaling Options

A number of Develocity components can be scaled horizontally to provide greater performance and higher availability.

values.yaml
global:
  scaling:
    replicas: 2

Develocity’s scalable components are implemented as Kubernetes Deployment resources. It is also possible to alter their replica count directly using kubectl scale, allowing integration with other Kubernetes tooling.

It is only recommended to alter the replica count directly when connecting to a user-managed database, as available embedded database connections are configured based on the replica count. The user-managed database should have (160 ✖️ replica count) connections available.

3. Database Options

Develocity can store data in either:

  • An embedded database that uses a local directory or volume to store its data.

  • A user-managed database that is completely separate from Develocity.

There are tradeoffs to consider for each option:

Embedded database tradeoffs

When using the embedded database, Develocity will run a PostgreSQL database in a container and store data in a persistent volume. In this mode Develocity can run backups on a regular or cron-like schedule.

The embedded database has several advantages:

  • Simple setup with no additional configuration needed.

  • Automatic updates to the latest PostgreSQL version supported.

  • Features that require disk space information are supported.

  • Typically more affordable for smaller installations.

However, there are downsides to the embedded database, in particular for larger installations:

  • Disk I/O throughput can be a bottleneck on a busy system and is difficult to address.

  • Backup management is slow for larger databases, creates a load on the server, and consumes a lot of memory.

  • It is not possible to keep a standby database.

  • The database is a single point of failure.

User-managed database tradeoffs

A user-managed database can be any PostgreSQL 12, 13, or 14 compatible database.

There are a number of advantages, particularly in large installations:

  • Database customizations and optimizations are possible (memory, CPU, I/O throughput, etc…​).

  • Resources can be allocated for cost-effectiveness.

  • Third party tools to snapshot the database can be used.

  • Many cloud databases allow for easy scaling of resources post installation.

  • A standby database for fail-over protection can be used.

There are some downsides to using a user-managed database:

  • Extra system(s) are needed for provisioning and configuration.

  • Database connectivity and network latency is a factor.

  • Backups must be managed by an administrator or a tool.

  • Disk space management and alerting are required.

  • Develocity features related to disk space are not available.

  • Security considerations such as credential cycling must be considered.

  • Customer support may be limited for disaster recovery or backup restores.

By default, Develocity will use an embedded database that stores its data in a persistent volume provided by the cluster. For this configuration, no additional values are needed in the Helm values file.

When Develocity is configured to store data in a user-managed database, it must be provided with connection settings and credentials for the database.

These can be provided either to Helm as configuration or as Kubernetes ConfigMap and Secret resources. Configuring these in Helm is the simplest approach during installation. Providing these values via external Kubernetes resources allows performing update (e.g. changing credentials) without having to rerun helm, and allows integration with other Kubernetes tooling (e.g. for Secret provisioning).

Standard connection settings like host, port and database name must be provided. Optionally, additional JDBC parameters can be specified.

values.yaml
database:
  location: user-managed
  connection:
    host: database.example.com
    port: 5432
    databaseName: gradle_enterprise
    params: "?connectTimeout=60"

These can also be provided as a ConfigMap. The name of the ConfigMap must be provided, and the resource itself must be created prior to starting Develocity.

values.yaml
database:
  location: user-managed
  connection:
    configMapName: my-example-db-connection-details

The ConfigMap is then configured like this:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-example-db-connection-details
data:
  host: database.example.com
  port: 5432
  dbname: gradle_enterprise
  jdbcParams: "?connectTimeout=60"

The port, dbname and jdbcParams properties are all optional. The default database name is gradle_enterprise.

The database must have already been created using CREATE DATABASE, the createdb command or an equivalent mechanism in a cloud database interface prior to configuring Develocity with connection details.

There are two options for credentials:

Option 1 - super user

If provided with credentials for a database superuser (such as the postgres user that is common on PostgreSQL database instances), Develocity can perform the database setup.

A superuser can be added to the values file in the database section:

values.yaml
database:
  location: user-managed
  connection: ...
  credentials:
    superuser:
      username: postgres
      password: the_password
In some installations, often cloud-based, the default credentials provided are not a superuser. For example, the supplied postgres account in Amazon RDS Postgres databases is not a superuser, but has the rds_superuser role. Such accounts are typically acceptable to use with Develocity.

These credentials can also be supplied as a Kubernetes Secret:

values.yaml
database:
  location: user-managed
  connection: ...
  credentials:
    superuser:
      secretName: my-example-db-superuser-credentials

The Secret should have the typical username and password keys, encoded using Base64:

---
apiVersion: v1
kind: Secret
metadata:
  name: my-example-db-superuser-credentials
data:
  username: "cG9zdGdyZXM="
  password: "ZXhhbXBsZS1wYXNzd29yZA=="
Option 2 - custom user

To set up your database without database superuser credentials, run the setup.sh script from the database setup scripts for your Develocity version against it. The script will set up less privileged accounts for the application to use, and some privileged functions needed for the application to run.

The installation will fail if you do not run the database setup scripts.

The credentials for the accounts must be set by the user and provided to Develocity via Helm configuration or Secrets.

To set up your database without database superuser credentials, the values file must be updated as follows:

values.yaml
database:
  location: user-managed
  connection: ...
  credentials:
    app:
      password: app_password
    migrator:
      password: migrator_password

These credentials can also be supplied as Secret resources. There are two accounts that must be configured, requiring a Secret each.

values.yaml
database:
  location: user-managed
  connection: ...
  credentials:
    app:
      secretName: my-example-db-application-credentials
    migrator:
      secretName: my-example-db-migrator-credentials

In this example stringData is used (which does not require Base64 encoding) to show the correct usernames to use. The usernames are currently not configurable.

---
apiVersion: v1
kind: Secret
metadata:
  name: my-example-db-application-credentials
stringData:
  username: ge_app
  password: "app-example-password"

---
apiVersion: v1
kind: Secret
metadata:
  name: my-example-db-migrator-credentials
stringData:
  username: ge_migrator
  password: "migrator-example-password"

4. Storage Settings

Storage Class Configuration

The Kubernetes StorageClass can be configured for data, logs and backup volumes. If omitted, the default storage class for the cluster will be picked, if there is one. Please consult your cluster documentation for available storage classes.

Not all clusters provide a useable default storage class. It’s strongly recommended to consult your cluster documentation and select from the available storage classes explicitly.
values.yaml
global:
  storage:
    data:
      class: some-provisioned-io-storage-class
    backup:
      class: slow-and-cheap-storage-class
Backup storage class is not necessary when connecting to a user-managed database.

Storage Capacity Configuration

Develocity needs a certain amount of storage for data, logs and backups. If omitted, the shown default amount of storage will be requested from the cluster.

values.yaml
database:
  storage:
    data:
      capacity: 1000Gi # default 250Gi
    backup:
      capacity: 1000Gi # default 250Gi
buildCacheNode:
  storage:
    data:
      capacity: 100Gi # default 10Gi
metrics:
  storage:
    data:
      capacity: 1Gi # default 200Mi
testDistribution:
  storage:
    data:
      capacity: 20Gi # default 10Gi
monitoring:
  storage:
    data:
      capacity: 20Gi  # Default 20Gi
objectStorage:
  type: embedded
  embedded:
    storage:
      data:
        capacity: 20Gi  # Default 10Gi
Backup storage capacity is not necessary when connecting to a user-managed database.

5. Routing Options

There are a number of ways to route web traffic to Develocity from outside the Kubernetes cluster. These include:

Which you choose to use will depend on your organisational policies and available infrastructure.

Supplied Ingress

Develocity can create a Kubernetes Ingress resource for you that is managed as part of your Helm release. The Ingress will be bound to the hostname that is configured.

values.yaml
ingress:
  enabled: true
Your Ingress-Controller implementation has to be compatible with GRPC to support some Develocity features (e.g. Bazel Build Scans). For more details about this, please consult your Ingress-Controller implementation.

User-managed Routing

For compatibility and configuration reasons, we strongly recommend to use the supplied Ingress definition. If the provided one is not suitable, you will need to provide your own configuration aligned with Develocity supplied Ingress.

Develocity creates a service named gradle-proxy exposing ports 80 and 443 (when HTTPS is enabled, see below) for accessing the application. This is the service to which alternative routing infrastructure such as load balancers will need to route traffic.

You may need to configure your Ingress differently to support Bazel using GRPC. Contact Develocity Customer Support for help with Bazel and your own Ingress definition.

OpenShift Configuration

Develocity needs to know when it is being deploying to an OpenShift cluster.

values.yaml
global:
  openshiftInstallation: true

6. Networking Options

There are a number of considerations for Develocity related to connectivity:

  • HTTP or HTTPS (with SSL certificates)

  • GRPC

  • Application Ports

  • Proxies

HTTP or HTTPs

Develocity can be configured to securely serve traffic over HTTPS based on user-provided certificates.

If certificates are not supplied, self-signed certificates will be generated and used, though this is not recommended for production operation.

HTTPS Terminated at Ingress

When using the Develocity supplied Ingress, HTTPS is enabled by default.

It can be disabled to serve traffic over HTTP only:

values.yaml
ingress:
  enabled: true
  ssl:
    enabled: false

SSL certificates (trusted or untrusted) can be provided inline in the values file:

values.yaml
ingress:
  enabled: true
  ssl:
    cert: |
      -----BEGIN CERTIFICATE-----
      MIIDKjCCAhKgAwIBAgIRAPNTIHf6/oUuzMKm3ffGNOgwDQYJKoZIhvcNAQELBQAw
      HDEaMBgGA1UEAxMRYXV0by1nZW5lcmF0ZWQtY2EwHhcNMjExMTMwMTU1NDU5WhcN
      ...
      Cn/3yUirFVTslrSYKAemLw8btLO6FDF9dc/lq1o7tKsYVuhEcjqnTah7puJjEN9h
      z+P5RmRxU/kaaFB+Vuw1pRezbaAtZNorVgXnBwrdseY4zLGyhAcGcR9v+VtCiQ==
      -----END CERTIFICATE-----
    key: |
      -----BEGIN RSA PRIVATE KEY-----
      MIIEpQIBAAKCAQEA4qV8JlqDMi7y85Ykq8dn7uIsi609D6KuFtlc+UvNYjatz0+u
      QzIr3iw//qf7sM8nx8fhGwuWvUWeCE6zbgKjuxDH82J9NQ0ctf70n0qVTeyW1CKR
      ...
      XlOfXr/xvkXA66PROgvVxfwpN/GNrLXFi1HvMg7MVZJUZQpNzpAzw5JTk2MbawOl
      G7tI0qQ6F20e5R4tPpEDKCFZykyvgGMhfLzsvVlrgaVW8QbVK4YWNtQ=
      -----END RSA PRIVATE KEY-----

Or the certificate can refer to a Kubernetes TLS Secret already available in the cluster:

values.yaml
ingress:
  enabled: true
  ssl:
    secretName: example-ssl-certificate-secret-name
HTTPS SSL Certificate

It is strongly recommended that production installations of Develocity are configured to use HTTPS with a trusted certificate.

Develocity natively supports serving traffic over HTTPS when configured with a certificate and key. If you intend to use an Ingress Controller for directing external traffic to Develocity, you may opt to terminate HTTPS there. It is also possible to terminate HTTPS connections in an external reverse proxy.

Untrusted SSL Certificates

By default, Develocity uses the default trust settings of the Java runtime that it ships with when connecting to other systems 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 (see below). This may be the case if you use self-signed certificates or an internal certificate authority.

Additional Certificates

Additional trusted certificates for outbound traffic can be specified at installation time via the unattended configuration mechanism, using the additionalTrust field in the unattended configuration file. The value of this field should be the X509 certificates to trust in PEM format, newline-separated if there are more than one.

For example, using the inline Helm values support to include the unattended configuration in a values file:

values.yaml
global:
    unattended:
      configuration:
        version: 5
        systemPassword: ...
        network:
         additionalTrust: |
             -----BEGIN CERTIFICATE-----
             MIIDfzCCAmegAwIBAgIURqPslYGu7cHXs22q3RK6e5L87PwwDQYJKoZIhvcNAQEL
             ...
             s10yB5VjVBES6A22rYwYb8mImpQiVP/mr4ao5U5m+h50l3E=
             -----END CERTIFICATE-----
             -----BEGIN CERTIFICATE-----
             DSE3a3CCAmegAwIBAgIURqPslYGu7cHXs22q3RK6e5L87PwwDQYJKoZIhvcNAQEL
             ...
             s10yB5VjVBES6A22rYwYb8mImpQiVP/mr4ao5U5m+h50l3E=
             -----END CERTIFICATE-----
HTTPS Terminated Externally

In many setups, a reverse proxy or load balancer will perform SSL termination. In this case, SSL certificates must be configured accordingly.

Develocity needs to know that the application will be accessed over externally terminated HTTPS. This is done with the following configuration:

values.yaml
global:
  hostname: develocity.example.com
  externalSSLTermination: true

If you’re using the provided Ingress, you may wish to communicate between the load balancer and the application using HTTP by disabling SSL at the Ingress:

values.yaml
ingress:
  enabled: true
  ssl:
    enabled: false

GRPC

Develocity uses the GRPC protocol for Bazel features. To support this, the application has to be exposed with grpc/http2 compatible components (e.g. Ingress-Controller, Firewall, Load balancers…).

Please consult the documentation of those infrastructure or Kubernetes components to get more information about support and requirements for grpc compatibility. All examples below use example annotations that are not relevant for your installation.

GRPC with Ingress annotations

Some Ingress-Controller implementations require extra implementation-specific annotations on Ingress objects to be compatible with grpc. You can provide them using the following entry in the values.yaml:

values.yaml
ingress:
  enabled: true
  grpc:
    annotations:
      acme.ingress.kubernetes.io/backend-protocol: "GRPC"
GRPC with Service annotations

Some Ingress-Controller implementations require extra implementation-specific annotations on Ingress objects to be compatible with grpc. You can provide them using the following entry in the values.yaml:

values.yaml
ingress:
  enabled: true
  grpc:
    serviceAnnotations:
      acme.ingress.kubernetes.io/upstream-protocol.h2c: "grpc"

Application Ports

The ports that the application accepts traffic on can be altered from the default of 443 (or 80 if accepting plain HTTP) as follows:

values.yaml
ingress:
  enabled: true
  port:
    http: 8080
    https: 8443

Proxy Configuration

By default, Develocity requires an internet connection to make several outbound HTTP requests (such as license validation).

In case your organization requires all outbound HTTP traffic to go through an HTTP proxy, you must perform additional configuration for this to work.

HTTP proxy configuration can be specified under the network section in the unattended configuration section:

values.yaml
global:
    unattended:
      configuration:
        version: 5
        systemPassword: ...
        network:
         proxy:
           protocol: http (1)
           host: proxy.gradle.com (2)
           port: 8080 (3)
           excludedHosts: (4)
             - some.external
             - '*.internal'
           auth: (5)
             username: proxy_user
             password: "aes256:B0uVHRDhng+PraUI:2bOz71vKTexz0QH5:z7lO+1wOC/tA3izLAwV0BXMugg=="
1 The protocol used to connect to the proxy. Note that this is not the protocol used to connect to the destination/target addresses. Supported values are http and https, if no value is provided http will be used as the default protocol.
2 HTTP proxy host name.
3 HTTP proxy port, if no value is provided 80 will be used ad the default port.
4 A comma-delimited list that controls what hosts should not be proxied. The list can contain individual host names as well as domain patterns (e.g. '*.internal') which match all hosts for a particular domain. Any requests sent to these hosts will be sent directly rather than being sent through the HTTP proxy.
5 A username and password used to authenticate with the HTTP Proxy.

5. Object Storage Configuration

Develocity can store two kinds of data using an object storage service, such as Amazon S3:

It is possible to separately configure whether object storage is used for each of these kinds of data. That is, it is possible to configure Develocity to store Build Scan data and not Build Cache data in an object store, or to store Build Cache data in an object store but not Build Scan data.

The Build Scan object storage section of the Administration Manual discusses the tradeoffs of using object storage rather than a database for Build Scan data. We recommend that your object storage is hosted close to your Develocity installation to minimise latency and network usage costs. For example, if using S3 as an object storage service, verify that your S3 bucket and Develocity installation reside in the same AWS region.

Most popular object storage services are supported. Alternatively, Develocity ships with the ability to run an embedded object store as one of its components. The rest of this section describes how to configure Develocity to use AWS S3, an S3-compatible object storage service, Google Cloud Storage, Microsoft Azure Blob Storage, or the embedded object storage.

To finish configuring Develocity to store build scans in the configured object storage, you must also configure Develocity with an unattended configuration stanza in your Helm values.yaml file. See Objects Storage for Build Scans for details.

Amazon S3

The S3 object storage section of the Amazon EKS Installation Guide describes steps for setting up a bucket in S3 with an appropriate access policy.

To use Amazon S3 as the object store for Develocity, you need to set the type of the object storage as s3 and configure the bucket name and region.

values.yaml
objectStorage:
  type: s3
  s3:
    bucket: example-bucket (1)
    region: <<region>> (2)
    credentials:
      #...
1 Your S3 bucket name.
2 The cloud provider region where your object storage resides.

It is necessary to provide credentials to access the bucket. There are several options to do this as documented below.

Direct credentials configuration

To provide an access key and secret key as credentials in the Helm chart, set source to configuration and provide the accessKey and secretKey.

values.yaml
objectStorage:
  type: s3
  s3:
    bucket: example-bucket
    region: example-aws-region-1
    credentials:
      source: configuration
      accessKey: "AKIA1234ABCD7890"
      secretKey: "dfml3s9rfdlsok390wledck30rkdfs"
Credentials configuration via Kubernetes secret

To provide an access key and secret key stored in a Kubernetes secret as credentials, set the secretName to the Kubernetes resource name of the secret. The secret must contain accessKey and secretKey properties.

values.yaml
objectStorage:
  type: s3
  s3:
    bucket: example-bucket
    region: example-aws-region-1
    credentials:
      secretName: s3-example-credentials
s3-example-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
  name: s3-example-credentials
stringData:
  accessKey: "AKIA1234ABCD7890"
  secretKey: "dfml3s9rfdlsok390wledck30rkdfs"

This option has the advantage of allowing credential cycling without needing to rerun Helm to reconfigure Develocity with the new credentials, and separating sensitive credentials from other settings.

Credentials sourced from the execution environment

It is possible to provision credentials to Develocity dynamically using EC2 instance profiles or EKS service accounts. Once these have been set up, set the credentials source to environment.

values.yaml
objectStorage:
  type: s3
  s3:
    bucket: example-bucket
    region: example-aws-region-1
    credentials:
      source: environment
Custom endpoint

There are circumstances in which it is necessary to specify the endpoint URL of the service:

  • If you need to connect to S3 directly from a VPC using a gateway VPC endpoint.

  • If your object storage service is not S3 but provides an S3-compatible interface.

To do this, set the endpoint property to point to the service endpoint:

values.yaml
objectStorage:
  type: s3
  s3:
    bucket: example-bucket
    endpoint: https://object-store.example.com
    credentials:
      #...

It is not necessary to specify a region when the endpoint is configured.

Google Cloud Storage

To use Google Cloud Storage as the object storage, set the type of object storage as googleCloud and configure the bucket.

values.yaml
objectStorage:
  type: googleCloud
  googleCloud:
    bucket: example-bucket
    credentials:
      #...

Develocity accesses the GCS bucket using the Interoperability API. Access keys can be created in the Google Cloud console on the Cloud Storage Interoperability page. Once created, you must configure Develocity with the access key and secret key, as documented below.

Direct credentials configuration

To provide the access key and secret key as credentials in the Helm chart, set source to configuration and provide the accessKey and secretKey.

values.yaml
objectStorage:
  type: googleCloud
  googleCloud:
    bucket: example-bucket
    credentials:
      source: configuration
      accessKey: "GOOG1234ABCD7890"
      secretKey: "dfml3s9rfdlsok390wledck30rkdfs"
Credentials configuration via Kubernetes secret

To provide an access key and secret key stored in a Kubernetes secret as credentials, set the secretName to the Kubernetes resource name of the secret. The secret must contain accessKey and secretKey properties.

values.yaml
objectStorage:
  type: googleCloud
  googleCloud:
    bucket: example-bucket
    credentials:
      secretName: gcs-example-credentials
gcs-example-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
  name: gcs-example-credentials
stringData:
  accessKey: "GOOG1234ABCD7890"
  secretKey: "dfml3s9rfdlsok390wledck30rkdfs"

This option has the advantage of allowing credential cycling without needing to rerun Helm to reconfigure Develocity with the new credentials, and separating sensitive credentials from other settings.

Azure Blob Storage

To use Azure Blob Storage as the object storage, set the type of the object storage as azure and configure the container name.

values.yaml
objectStorage:
  type: "azure"
  azure:
    container: example-container
    credentials:
      #...

It is necessary to provide credentials to access the bucket. Develocity supports two different mechanisms for supplying credentials:

  • Specify a single connection string

  • Specify a Shared Access Secret (SAS) and an endpoint for the Azure storage account.

There are several options to supply these as documented below.

Direct connection string configuration

To provide a connection string in the Helm chart, set source to connectionString and provide the connectionString.

values.yaml
objectStorage:
  type: azure
  azure:
    container: example-container
    credentials:
      source: connectionString
      connectionString: "DefaultEndpointsProtocol=https;AccountName=exampleaccount;AccountKey=dfml3s9rfdl==;EndpointSuffix=core.windows.net"
Direct Session Access Signature configuration

To provide a SAS in the Helm chart, set source to sas and provide the sas and endpoint.

values.yaml
objectStorage:
  type: azure
  azure:
    container: example-container
    credentials:
      source: sas
      sas: "dfml3s9rfdlsok390wledck30rkdfs"
      endpoint: https://exampleaccount.blob.core.windows.net
Credentials configuration via Kubernetes secret

To provide either above type of credential stored in a Kubernetes secret, set the secretName to the Kubernetes resource name of the secret. The secret must contain either a connectionString or a sas and endpoint pair.

values.yaml
objectStorage:
  type: azure
  azure:
    container: example-bucket
    credentials:
      secretName: azure-example-credentials
azure-example-credentials-connection-string.yaml
apiVersion: v1
kind: Secret
metadata:
  name: gcs-example-credentials
stringData:
  connectionString: "DefaultEndpointsProtocol=https;AccountName=exampleaccount;AccountKey=dfml3s9rfdl==;EndpointSuffix=core.windows.net"
azure-example-credentials-sas.yaml
apiVersion: v1
kind: Secret
metadata:
  name: gcs-example-credentials
stringData:
  sas: "dfml3s9rfdlsok390wledck30rkdfs"
  endpoint: "https://exampleaccount.blob.core.windows.net"

This option has the advantage of allowing credential cycling without needing to rerun Helm to reconfigure Develocity with the new credentials, and separating sensitive credentials from other settings.

Embedded object Storage

Embedded object storage is a component that is deployed as part of the Develocity installation if no other object storage is configured.

The type of the object storage is embedded.

values.yaml
objectStorage:
  type: embedded

Data will be stored on a persistent volume. See Storage Capacity Configuration for details on specifying the capacity of the embedded object storage.

Build Scans cannot be stored in embedded object storage. See the relevant section of the Administration Manual for more information on setting the storage type for incoming build scans using unattended configuration.
Data in the embedded object store is not part of a Develocity database backup.

Configuring advanced parameters

Each object storage provider can be further configured using advancedParams. You should only configure advanced parameters if you have been directed to do so by Develocity support.

values.yaml
objectStorage:
  type: s3
  s3:
    bucket: example-bucket
    region: example-aws-region-1
    credentials:
      source: "environment"
    advancedParams:
      client.maxConcurrency: 12
      connection.endpoint: http://custom-s3-endpoint

8. Unattended Configuration

Many aspects of Develocity’s behaviour can be configured via the Admin user interface or by providing an unattended configuration file. These settings are described in the unattended configuration section of the Develocity Administration Manual.

Unattended configuration settings can also be in their own yaml file and given to the helm command as follows: --set-file global.unattended.configuration=./unattended-config.yaml

While most of Develocity can be configured post-installation, the Proxy settings should be configured at installation time.

In order to use the unattended configuration in your Helm values file, you will need the hashed system user password and a configuration version. The Develocity Admin CLI must also be installed. Full instructions are available in the Administration Manual.

Having prepared a Develocity configuration file and optionally an encryption key, you can provide it to Helm in one of two ways.

Example key:

develocity-configuration.key
aes256:B0uVHRDhng+PraUI:Aj25DOwJsrXnWYcprreHAS4l66k/7q5CIjFDg5PTR7U=

Example yaml file:

develocity-configuration.yaml
version: 6
systemPassword: "ObvvvqQww04Fn2jLBOOgjZDkXGL06fNmpueVcdk1lz0=:dBLNuLA/+qiwOqBQKf5pW89SV5mcQBJ4Vph/7lXerdD+2sLM8jij+2WJbBwXsqJ+mJugsveuUb+DyU3LBgkqcg=="
buildScans:
  keepDays: 30
email:
  administratorAddress: develocity-adminstrator@example.com
  fromAddress: develocity@example.com
  smtpServer: smtp.example.com:587
  sslProtocol: startTls
  authentication:
    type: login
    username: develocity-adminstrator@example.com
    password: "aes256:B0uVHRDhng+PraUI:2bOz71vKTexz0QH5:z7lO+1wOC/tA3izLAwV0BXMugg=="

The file and encryption key can be provided inline in a Helm values file under the global.unattended property:

values.yaml
global:
  unattended:
    key: "aes256:B0uVHRDhng+PraUI:Aj25DOwJsrXnWYcprreHAS4l66k/7q5CIjFDg5PTR7U=" (1)
    configuration: (2)
      version: 6
      systemPassword: "ObvvvqQww04Fn2jLBOOgjZDkXGL06fNmpueVcdk1lz0=:dBLNuLA/+qiwOqBQKf5pW89SV5mcQBJ4Vph/7lXerdD+2sLM8jij+2WJbBwXsqJ+mJugsveuUb+DyU3LBgkqcg=="
      buildScans:
        keepDays: 30
      email:
        administratorAddress: develocity-adminstrator@example.com
        fromAddress: develocity@example.com
        smtpServer: smtp.example.com:587
        sslProtocol: startTls
        authentication:
          type: login
          username: develocity-adminstrator@example.com
          password: "aes256:B0uVHRDhng+PraUI:2bOz71vKTexz0QH5:z7lO+1wOC/tA3izLAwV0BXMugg=="
1 The encryption key used for any secrets in your configuration. In this example, the password for email authentication is encrypted. Not required if the configuration does not contain any encrypted passwords. Note that the systemPassword is a hashed value, not an encrypted one, and so does not require an encryption key.
2 The Develocity configuration yaml is put inline underneath this property. Content needs to be indented such that it is all correctly under the global.unattended.configuration property.

Or they can be supplied as helm arguments using --set-file:

$ (helm command) \
    --set-file global.unattended.configuration=path/to/develocity-configuration.yaml \
    --set-file global.unattended.key=path/to/develocity-configuration.key
Develocity configuration that is set in Helm like this will not be reapplied (i.e. overwrite manual changes made in the Admin UI) in subsequent installations unless the contents of the config file(s) has changed.

Proxy Settings

HTTP proxy configuration can be specified under the network section in the unattended configuration section:

values.yaml
global:
    unattended:
      configuration:
        version: 5 (1)
        systemPassword: "«hashed-system-password»" (2)
        network:
         proxy:
           protocol: http (3)
           host: proxy.gradle.com (4)
           port: 8080 (5)
           excludedHosts: (6)
             - some.external
             - '*.internal'
           auth: (7)
             username: proxy_user
             password: "aes256:B0uVHRDhng+PraUI:2bOz71vKTexz0QH5:z7lO+1wOC/tA3izLAwV0BXMugg=="
1 The version of the unattended config. See the Administration Manual.
2 The hashed system user password. See the Administration Manual.
3 The protocol used to connect to the proxy. Note that this is not the protocol used to connect to the destination/target addresses. Supported values are http and https, if no value is provided http will be used as the default protocol.
4 HTTP proxy host name.
5 HTTP proxy port, if no value is provided 80 will be used ad the default port.
6 A comma-delimited list that controls what hosts should not be proxied. The list can contain individual host names as well as domain patterns (e.g. '*.internal') which match all hosts for a particular domain. Any requests sent to these hosts will be sent directly rather than being sent through the HTTP proxy.
7 A username and password used to authenticate with the HTTP Proxy.

Objects Storage for Build Scans

To configure Develocity to store incoming Build Scan data using your object storage service bucket or container, add the following to your Helm values file:

values.yaml
global:
  unattended:
    configuration:
      version: 9 (1)
      systemPassword: "«hashed-system-password»" (2)
      buildScans:
        storage:
          incomingStorageType: objectStorage
      advanced:
        app:
          heapMemory: 5632 (3)
objectStorage: (4)
  type: s3
  s3:
    bucket: example-bucket
    region: «region»
    credentials:
      source: environment
1 The version of the unattended configuration. See the Administration Manual.
2 Your hashed system password. See the Administration Manual.
3 If you have already set a custom value here for heap memory, increase it by 2048.
4 The object storage stanza you created in 5. Object Storage Configuration. If you set incomingStoragetype to objectStorage, then you must configure an object storage service with this stanza in values.yaml for your Develocity instance.

This example uses S3 with environment-source credentials, but your object storage configuration may be different.

9. Using an external Bazel cache

If you wish to use Build Scans for your Bazel builds while using a remote cache other than the one built into Develocity, you will need to configure the necessary details. Please note that your remote cache must expose a GRPC endpoint for Develocity to be able to speak to it.

The only mandatory value is the host and port of your external cache:

values.yaml
enterprise:
    bazel:
        remoteCacheConnection:
            url: grpc{s}://<hostname>:<port>

If your external cache allows anonymous reads, this is the only value you need. Otherwise, see the section on authentication.

Authenticating to an external Bazel cache

All configuration of authentication to a Bazel cache will take the following form:

values.yaml
enterprise:
    bazel:
        remoteCacheConnection:
            url: grpc{s}://<hostname>:<port>
            authType: <AUTH_TYPE>
            auth:
                <AUTH_TYPE>:
                    ...

Please note that any credentials you provide must allow a user to read from the cache.

The following authentication methods are currently supported:

Bearer token authentication

In this authentication method, an external token will be passed to the server in the Authorization header prefixed by "Bearer" - Bearer <token>. The configuration for this scenario should look like this:

values.yaml
enterprise:
    bazel:
        remoteCacheConnection:
            url: grpc{s}://<hostname>:<port>
            authType: bearerToken
            auth:
                bearerToken:
                    token: <TOKEN>
TLS client authentication

In this authentication method, a client certificate + key will be used to authenticate to the cache. Please note that the certificate and key must be separate values and in PEM format. You can provide these values directly, in which case the configuration looks like this:

values.yaml
enterprise:
    bazel:
        remoteCacheConnection:
            url: grpc{s}://<hostname>:<port>
            authType: tls
            auth:
                tls:
                    cert: |-
                        <PEM_FORMATTED_CERT>
                    key: |-
                        <PEM_FORMATTED_KEY>

If you do not wish to include these values in your YAML file, you may create a TLS Secret in your cluster in the same namespace where you are installing Develocity and then pass in the name of that secret:

values.yaml
enterprise:
    bazel:
        remoteCacheConnection:
            url: grpc{s}://<hostname>:<port>
            authType: tls
            auth:
                tls:
                    secretName: <SECRET_NAME>

10. Airgap Installations

Develocity can be run on hosts without internet connectivity, referred to as an airgap installation.

Airgap Configuration

In an airgap installation, Helm is configured so that no attempt is made to pull images from the outside world with the values below:

values.yaml
global:
  image:
    imagePullPolicy: Never

Your values.yaml file is complete. You can return to the installation manual.

Appendix A: Background Processing Configuration

Depending on the volume and frequency of your builds, background tasks for newly uploaded Build Scans can require a significant amount of CPU and memory. Moreover, some upgrades or configuration changes of Develocity require reprocessing existing builds to extract new data. For example, when enabling Predictive Test Selection for the first time all existing builds will be processed to collect change and test execution history.

Therefore, background work can optionally be processed in a separate pod that can be scaled independently of other components to avoid any adverse effect on the Develocity frontend. You should only enable background processing after being prompted by the Develocity support team.

Enabling the background processor will increase hardware resource requirements. It also increases required number of database connections when a user managed database is used (80 connections ✖️ background processor replica count).
values.yaml
enterpriseBackgroundProcessor:
  enabled: true
  scaling:
    replicas: 2

Appendix B: Example Helm Values File

You can download and verify the example Helm values file with the following commands:

$ curl -L -o example.values.yaml https://docs.gradle.com/enterprise/helm-standalone-installation/values-2024.1/gradle-enterprise-standalone-values-2024.1.yaml
$ curl -L -o example.values.yaml.sha256 https://docs.gradle.com/enterprise/helm-standalone-installation/values-2024.1/gradle-enterprise-standalone-values-2024.1.yaml.sha256
$ echo "$(cat example.values.yaml.sha256)  example.values.yaml" | sha256sum -c

A direct download is available below:

Appendix C: Database Setup Scripts

Appendix D: Upgrading to Develocity 2024.1

The 2024.1 release provides a new Develocity build cache service that replaces the existing service. The release also marks the general availability of object-based storage for the build cache, which improves the horizontal scalability of the Develocity-provided build cache. Gradle encourages Develocity administrators to use a cloud-based object storage service, such as AWS S3, to provide high scalability and fault tolerance. However, if this is not desirable or possible, administrators may store build cache artifacts within the Develocity-provided embedded object storage.

The following table describes the upgrade impact of two Kubernetes cluster installation scenarios. See Unattended Configuration in the Develocity Administration Manual for more information about the unattended configuration section of the values.yaml configuration file discussed in the following tasks. If you need assistance with your upgrade, create a support bundle using the Develocity Admin CLI and share it by opening a ticket at https://support.gradle.com.

If your existing build cache node uses more than 8 GiB of memory or has a cache size larger than 1 TB, contact customer support to properly size the new build cache service before you upgrade.

Scenario

Description

Upgrade Kubernetes cluster installation with no object storage configured

After upgrading to 2024.1, the Develocity build cache service migrates existing and begins storing new cache artifacts within embedded object storage. Develocity creates a new Kubernetes persistent volume and persistent volume claim with a default of 10 GiB.

Upgrade Kubernetes cluster installation with external object storage configured

After upgrading to 2024.1, build cache artifacts are stored in object storage along with build scans. Develocity migrates build cache artifacts from the legacy built-in build artifacts node to your external object storage service, which increases the space used for external storage. The used disk space, however, can be reduced by the amount of space previously used by the build cache. See (Optional) Disable the legacy built-in build cache node for instructions.

Before you use the unattended configuration feature for the first time, it’s crucial to export your current configuration to serve as a reference. This ensures that you do not accidentally overwrite any settings that were initially configured through the UI.

To download your existing configuration:

  1. Navigate to the Import/Export section in the admin panel by visiting https://<your-develocity-hostname>/admin/import-export/export.

  2. Follow the instructions to download your configuration.

By using your current configuration as a baseline, you can safely make changes without losing any initial setups.

Task 1: Increase the Kubernetes pod memory requests and limits by the amount of heap memory for the built-in build cache node

Increase the memory requests and limits of the enterprise-app pod by the amount of heap memory for the built-in build cache node. You can find the current value by navigating to https://<your-develocity-hostname>/admin/advanced and checking the value of Heap memory (MiB). Then, update the requests and limits fields in the enterprise section of your values.yaml configuration file:

enterprise:
  resources:
    requests:
      memory: <existing-value_plus_built-in-build-cache-node-heap-memory> (1)
    limits:
      memory: <existing-value_plus_built-in-build-cache-node-heap-memory> (2)
1 This sets the new value for request memory equal to the existing value plus the value set for the built-in-build cache node.
2 This sets the new value for request limits equal to the existing value plus the value set for the built-in-build cache node.

Task 2: Increase the application heap memory settings by the amount allocated for the built-in build cache node

Increase the Develocity application heap memory by the amount of heap memory configured for the build cache. You can find the current value by navigating to https://<your-develocity-hostname>/admin/advanced and checking the value of Heap memory (MiB). Then, update the heapMemory field in the unattended configuration section of your values.yaml configuration file:

global:
  unattended:
    configuration:
      systemPassword: <base64-encoded-hashed-password> (1)
      version: 9
      advanced:
        app:
          heapMemory: <existing-value_plus_built-in-build-cache-node-heap-memory> (2)
1 Required value. See Hashing the system password in the Develocity Administration Manual for instructions.
2 This sets the heap memory equal to the existing value plus the value set for the built-in-build cache node.

Task 3: Verify target storage size

If your Develocity installation currently has a built-in build cache node with a target cache size greater than the 10 GiB default, update your values.yaml configuration file to ensure that the cache size is not reverted to the default. You can verify the current value by navigating to https://<your-develocity-hostname>/cache-admin/node/built-in and checking the value of Target cache size (MiB). Then, update the storageSize field in the unattended configuration section of your values.yaml configuration file:

global:
  unattended:
    configuration:
      buildCache:
        storageSize: 150000 (1)
1 This sets the target storage size to 150 GiB.

Next, update the value of capacity in the objectStorage stanza of your Helm values.yaml configuration file:

objectStorage:
  type: embedded
  embedded:
    storage:
      data:
        capacity: 150Gi  # default 10 Gi (1)
1 This increases the default storage capacity by 140 GiB.
If you do not edit your values.yaml configuration file for a non-default target storage size, the upgrade will revert to the default, 10 GiB, and migrate only the most recent 10 GiB of cache entries to the new build cache node service.

Task 4: Verify maximum artifact size

If your Develocity installation currently has a maximum artifact size set to any value other than the 100 MiB default, update your values.yaml file with this value. You can verify the current value by navigating to https://<your-develocity-hostname>/cache-admin/node/built-in and checking the value of Maximum artifact size (MiB). Then, update the maxArtifactSize field in the unattended configuration section of your values.yaml configuration file:

global:
  unattended:
    configuration:
      buildCache:
        maxArtifactSize: 200 (1)
1 This sets the maximum artifact size to 200 MiB.

Example Helm configuration file

The following example values.yaml file contains all the fields discussed in this appendix:

global:
  unattended:
    configuration:
      systemPassword: <base64-encoded-hashed-password> (1)
      version: 9
      advanced:
        app:
          heapMemory: <existing-value_plus_built-in-build-cache-node-heap-memory> (2)
      buildCache:
        storageSize: 150000 (3)
        maxArtifactSize: 200 (4)

enterprise:
  resources:
    requests:
      memory: <existing-value_plus_built-in-build-cache-node-heap-memory> (5)
    limits:
      memory: <existing-value_plus_built-in-build-cache-node-heap-memory> (6)

objectStorage:
  type: embedded
  embedded:
    storage:
      data:
        capacity: 150Gi # default 10 Gi (7)
1 Required value. See Hashing the system password in the Develocity Administration Manual for instructions.
2 This sets the heap memory equal to the existing value plus the value set for the built-in-build cache node.
3 This sets the target storage size to 150 GiB.
4 This sets the maximum artifact size to 200 MiB.
5 This sets the new value for request memory equal to the existing value plus the value set for the built-in-build cache node.
6 This sets the new value for request limits equal to the existing value plus the value set for the built-in-build cache node.
7 This increases the default storage capacity by 140 GiB.

(Optional) Disable the legacy built-in build cache node

The Administration UI notifies Develocity administrators when they can remove the legacy built-in build cache node. Removing the legacy node frees memory and storage resources.

legacy bcn node removal notice

To disable the legacy built-in build cache node, edit the following value in your values.yaml configuration file:

global:
buildCacheNode:
  enabled: false

Next, remove the persistent volume claim used by the built-in build cache node with the following command:

kubectl -ns <develocity-namespace> delete pvc gradle-build-cache-volume

If your reclaim policy does not automatically remove the persistent volume, remove it with the following command:

kubctl -ns <develocity-namespace> delete pv build-cache