Version 2023.3

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

Helm manages all Gradle Enterprise 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 Gradle Enterprise installation with information such as networking, database, or hostname settings.

Here is a sample values.yaml file:

values.yaml
global:
  hostname: ge.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 Gradle Enterprise 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 Gradle Enterprise installation options and their corresponding values.yaml variables:

  1. Global Options (Hostname, License)

  2. Database Type (Embedded or External)

  3. Storage Settings

  4. Networking Options (Ports, Proxies, SSL)

  5. Object Storage

  6. Unattended Configuration

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 Gradle Enterprise installation with storage, networking, database settings, and more.

Helm Options

1. Global Options

Hostname

When installing Gradle Enterprise, a hostname such as ge.example.com is required.

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 Gradle Enterprise host or the hostname of a reverse proxy if one is being used.

Gradle Enterprise 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: ge.example.com

License

You have been provided with a Gradle Enterprise license file called gradle-enterprise.license.

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

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.

2. Database Options

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

There are tradeoffs to consider for each option:

Embedded database tradeoffs

When using the embedded database, Gradle Enterprise will run a PostgreSQL database in a container and store data in a local directory. In this mode Gradle Enterprise 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. Popular options also include cloud-based database providers such as Amazon RDS or Aurora. 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.

  • Gradle Enterprise 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, Gradle Enterprise will use an embedded database. For this configuration, no additional values are needed in the Helm values file.

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

Standard connection settings like host, port, and database name must be provided in the values file. JDBC parameters can be optionally specified as well:

values.yaml
database:
  location: user-managed
  connection:
    host: database.example.com (1)
    port: 5432 (2)
    databaseName: gradle_enterprise (3)
    params: "?connectTimeout=60" (4)
1 The database URL.
2 The port property is optional.
3 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 Gradle Enterprise with connection details.
4 The params property is optional.

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), Gradle Enterprise 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 Gradle Enterprise.
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 Gradle Enterprise 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 Gradle Enterprise via Helm configuration.

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

3. Storage Settings

The Gradle Enterprise standalone distribution will store its data in a specified directory.

By default, this directory is /opt/gradle. Logs and backups are stored in subdirectories of that directory.

To alter the location of backups, the values.yaml file can be updated as follows:

values.yaml
global:
  storage:
    directory: /mnt/big-volume/ge           # Default /opt/gradle
    backup:
      directory: /mnt/vol2/ge-backups       # Default (global.storage.directory)/backups

4. Networking Options

There are a number of considerations for Gradle Enterprise related to connectivity:

  • HTTP or HTTPS (with SSL certificates)

  • Application Ports

  • Proxies

HTTP or HTTPs

Gradle Enterprise 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 Gradle Enterprise 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-----
This file can also be passed using the --set-file flag with your helm command.
HTTPS SSL Certificate

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

Gradle Enterprise 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 Gradle Enterprise, 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, Gradle Enterprise 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. This may be the case if you use self-signed certificates or an internal certificate authority.

Trusted and Additional SSL Certificates

Additional trusted certificates 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 config 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.

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

values.yaml
global:
  hostname: ge.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

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, Gradle Enterprise 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 as part of the unattended configuration.

7. Object Storage Configuration

Gradle Enterprise can store data in a configured object store such as Amazon S3 in a couple of ways:

  • By default, Gradle Enterprise stores Build Scan data in the database, but can be configured to store it in an object store.

  • In Gradle Enterprise 2023.3 it is also possible to store Build Cache data in an object store rather than the default file storage.

See Build Scan object storage in the Administration Manual for tradeoffs of using object storage rather than a database. Due to latency and traffic costs, Gradle recommends using object storage that is hosted close to your Gradle Enterprise installation. For example, if using S3 for object storage, verify that your S3 resource and Gradle Enterprise installation reside in the same AWS region.

No object storage configuration in Helm is required to get the default behaviour. To store data in an object store you must provision a container or bucket with a storage provider and configure Gradle Enterprise with connection settings and credentials.

Amazon S3

See here for steps on setting up a bucket in S3 with an appropriate access policy.

To use AWS S3 as the object storage, 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
    region: example-aws-region-10
    credentials:
      #...

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 Gradle Enterprise with the new credentials, and separating sensitive credentials from other settings.

Credentials sourced from the execution environment

It is possible to provision credentials to Gradle Enterprise 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 store 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:
      #...

Gradle Enterprise 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 Gradle Enterprise 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 Gradle Enterprise 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. Gradle Enterprise 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 Gradle Enterprise with the new credentials, and separating sensitive credentials from other settings.

Embedded Object Storage

If no external object store is configured, Gradle Enterprise can use an embedded object store to store Build Cache data. To use the embedded object storage, set the type of the object storage as embedded.

values.yaml
objectStorage:
  type: embedded

Data will be stored on the local disk under the configured storage directory.

6. Unattended Configuration

Many aspects of Gradle Enterprise’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 Gradle Enterprise 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 Gradle Enterprise can be configured post-installation, there are two items that can and should be configured at installation time:

  • Proxy settings

  • S3 for Build Scans (AWS users only)

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 Gradle Enterprise Admin CLI must also be installed. Full instructions are available in the Administration Manual.

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 unnattended configuration. See the Administration Manual.
2 Your hashed system 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.

S3 for Build Scans

To use your S3 bucket, add the following to your Helm values file:

values.yaml
global:
  unattended:
    configuration:
      version: 5 (1)
      systemPassword: "«hashed-system-password»" (2)
      buildScans:
        storage:
          incomingStorageType: s3
          s3:
            bucket: gradle-enterprise-build-scans-«account-id» (3)
            region: «region» (4)
            credentials:
              source: environment
      advanced:
        app:
          heapMemory: 5632 (5)
1 The version of the unattended configuration. See the Administration Manual.
2 Your hashed system password. See the Administration Manual.
3 Your account ID.
4 The region of your S3 bucket.
5 If you have already set a custom value here, increase it by 2048.

7. Airgap Installations

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

Appendix A: 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-2023.3/gradle-enterprise-standalone-values-2023.3.yaml
$ curl -L -o example.values.yaml.sha256 https://docs.gradle.com/enterprise/helm-standalone-installation/values-2023.3/gradle-enterprise-standalone-values-2023.3.yaml.sha256
$ echo "$(cat example.values.yaml.sha256)  example.values.yaml" | sha256sum -c

A direct download is available below: