---
component: ROOT
version: "2026.3"
slug: ROOT/installation/kubernetes-installation
canonical_url: "https://docs.develocity.ai/2026.3/installation/kubernetes-installation/"
title: "Self-Hosted Kubernetes Installation Guide"
description: "Install and configure Develocity on an existing Kubernetes cluster with Helm, covering resource and storage requirements, chart values, and rollout."
keywords:
  - "Helm chart"
  - "Kubernetes"
  - "cluster"
status: current
---

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

# Self-Hosted Kubernetes Installation Guide

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

This manual covers the installation of [Develocity](https://develocity.ai/) into an existing Kubernetes cluster.

Develocity is a Kubernetes-based application, distributed as a [Helm](https://helm.sh/) chart. Helm is a package manager for Kubernetes applications. In a Kubernetes installation, you use Helm to install Develocity into an existing cluster. [Helm](https://helm.sh/docs/intro/using_helm/) manages all Develocity components.

For instructions on installing Develocity on a host without public network connectivity, see [Airgap Installation](#airgap_install).

<a id="prerequisites"></a>

## Prerequisites

<a id="get_license"></a>

### A Develocity License

If you have purchased Develocity or started a trial, you should already have a license file called `develocity.license`. Otherwise, you can [request a Develocity trial license](https://develocity.ai/trial/).

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

## Cluster Requirements

> [!NOTE]
> Develocity only supports the x86\_64 architecture.

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

### Kubernetes Versions

Compatibility between versions of Kubernetes, Helm and Develocity can be found on the [version overview matrix](https://docs.develocity.ai/2026.3/miscellaneous/compatibility/#kubernetes_and_helm).

When installing Develocity, if the versions of Kubernetes or Helm you are using are lower than the supported versions, the installation fails.

If you accept the risk of running on an unsupported version, you can bypass this check using the `helmVersionOverride` and `kubernetesVersionOverride` values. Develocity validates the versions you set here instead of the versions you actually have installed, so setting them to a supported version makes the check pass even when your real Helm or Kubernetes version is older.

These values do not change what you run. They only control which versions Develocity validates against. Set them to the minimum supported version, which is the simplest value that satisfies the check.

> [!WARNING]
> Overriding these values disables Develocity’s version compatibility check. Running on unsupported versions of Helm or Kubernetes is at your **own** risk.

🔍 **Example of overriding the version check**

Set the overrides to the minimum supported versions so the compatibility check passes. These are not the versions you are running. They are the values Develocity validates against.

**values.yaml:**

```
global:
  helmVersionOverride: "3.20.0"
  kubernetesVersionOverride: "1.33.0"
```

<a id="platform"></a>

### Kubernetes Platforms

Develocity does not use any platform-specific features and works on all platforms.

Gradle has verified Develocity on [K3s](https://k3s.io/), [Amazon EKS](https://aws.amazon.com/eks/), [Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift), [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/products/kubernetes-service/).

<a id="helm"></a>

### Helm Requirements

Check the [Helm Version Support Policy](https://helm.sh/docs/topics/version_skew/) to ensure compatibility with your Kubernetes version.

<a id="resource_requirements"></a>

### Resource Requirements

<a id="node_group_specification"></a>

#### Node Group Specification

The recommended node group specification for a cluster is **5** nodes, each with **4** CPU units and **16** GiB of memory.

<a id="resource-requests-and-limits"></a>

#### Resource Requests and Limits

The total [resource requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) for the Develocity Helm Chart are as follows:

*   Resource requests (the minimal resources required by the application to start): **14 CPU units**, **26 GiB memory**.
    
*   Resource limits (the maximum resources that might be used by the application if available): **22 CPU units**, **39 GiB memory**.
    

<a id="database"></a>

### Database

By default, Develocity stores its data in a **PostgreSQL database** that runs as part of the application itself. The data lives in a persistent volume. This is the **embedded database**.

<a id="user_managed_database_compatibility"></a>

You can also store Build Scan, Build Cache node, and test distribution data in a **user-managed database**. A user-managed database can be any PostgreSQL database compatible with versions 15 through 18. The [compatibility matrix](https://docs.develocity.ai/2026.3/miscellaneous/compatibility/#user_managed_database) lists the supported versions for every Develocity release.

<a id="storage"></a>

### Storage

Develocity uses [persistent volume claims](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) for storing data and backups. Develocity uses your cluster’s default [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/#default-storageclass) if it has one.

If no default StorageClass is configured, or you want to use a different one, provide the name of the StorageClass to use for provisioning persistent volumes.

Different StorageClasses can be specified for the different types of storage used.

> [!NOTE]
> Use faster StorageClasses for data, and a separate slower, cost-efficient one for backups.

Some Pods use multiple persistent volumes. On Kubernetes platforms with multiple availability zones, those Pods and their persistent volumes must sit in the same zone. In this case, use a StorageClass with a `volumeBindingMode` of `WaitForFirstConsumer` to ensure that all persistent volumes are provisioned in the same zone that the pod was scheduled in.

Where available, use StorageClasses that allow [persistent volume claim expansion](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#expanding-persistent-volumes-claims). Expanding storage is then straightforward as your Develocity usage grows.

<a id="storage_requirements_capacity"></a>

#### Capacity

The recommended minimum capacities for the persistent volumes are:

 
| Description | Size in GiB |
| --- | --- |
| Build Scan data | 250 |
| Build Scan data backups | 250 |
| Edge Node | 50 |
| Test Distribution | 10 |
| Embedded Object Storage | 80 |

> [!NOTE]
> The embedded object storage provisions a single persistent volume sized to the sum of `objectStorage.embedded.storage.internalBuffer.capacity` (default `5Gi`), `objectStorage.embedded.storage.buildCache.capacity` (default `50Gi`, which holds the durable Build Cache content, including artifacts uploaded from co-located and externally provisioned Edge nodes), `objectStorage.embedded.storage.monitoring.capacity` (default `20Gi`, which holds the monitoring metrics), and `objectStorage.embedded.storage.monitoring.logging.capacity` (default `5Gi`, which holds the monitoring logs). Adjust the sub-settings to change the overall PV size.

> [!NOTE]
> The Edge node volume provides a low-latency cache for build agents. For optimal read speeds, this volume must be placed on local SSD block storage. Do not use network file systems (NFS) or remotely-mounted volumes. Remote storage introduces significant latency, negating the performance benefits of the cache. The volume is ephemeral, so it is not retained across Pod restarts, updates, or scale-down. After such an event, the cache starts empty and warms on demand. As builds request entries, the new Pod fetches them from peer Edge nodes. On a miss, it fetches them through Develocity from the durable Object Storage. Expect temporarily reduced performance while the cache warms this way. Reads are still served, but from Object Storage rather than the local volume until the working set is warm again. If the durable Object Storage sits in a different region than the cluster, this refill traffic also increases Develocity’s cross-region read volume. Entries served from Object Storage still register as ordinary remote-cache hits. As a result, the extra warm-up latency does not surface as a distinct signal in the Build Scan. When troubleshooting a slow build that follows an Edge node restart, correlate it with the restart event. No data is lost: the durable copy remains in the Object Storage connected to Develocity.

Adjust its size with `edgeNode.storage.data.capacity`, or see the [Edge Node](https://docs.develocity.ai/2026.3/reference/helm-charts/cluster/#edge_node) configuration to scale it.

If you are producing a lot of Build Scan data in a day (> 1GB) or intend to retain Build Scan data for long periods of time (30 days+) you might want to consider provisioning more storage. If your StorageClass does not allow expanding volumes, you should also consider preparing for future data growth by adding additional disk capacity upfront.

<a id="performance"></a>

#### Performance

For production workloads, the data StorageClass should exhibit SSD-class disk performance of at least **3000 IOPS** (input/output operations per second). The StorageClass for backup volumes can be slower.

> [!NOTE]
> Disk performance has a significant impact on Develocity performance. Network file systems (such as Amazon EFS) are not compatible with Develocity due to their performance characteristics.

<a id="object-storage"></a>

#### Object Storage

Develocity administrators can store Build Scan® data and monitoring data such as metrics and logs in an object storage service, such as [Amazon S3](https://aws.amazon.com/s3/), [Google Cloud Storage](https://cloud.google.com/storage), and [Microsoft Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs). This can help performance in high-traffic installations by reducing the load on the database. Object storage services offer performance and cost advantages compared to database storage. If you deploy Develocity to a cloud provider or have an available internal S3-compatible object store, Gradle recommends using object-based storage for your installation. See [Build Scan object storage](https://docs.develocity.ai/2026.3/administration/build-scan/build-scan-storage/#build_scan_object_storage) in the Develocity Administration Manual for a description of the benefits and limitations.

<a id="networking"></a>

### Networking

By default, Develocity requires a cluster whose nodes can pull images from the internet. It also requires network connectivity for periodic license validation.

> [!WARNING]
> An installation of Develocity does not start if it cannot connect to both `registry.gradle.com` and `harbor.gradle.com`.

**For clusters with limited or no internet connectivity, follow the Airgap installation steps.**

The next sections cover the networking options you need to decide on before [Helm Configuration](#helm_config).

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

#### Verifying Connectivity

Internet connectivity to `https://helm.gradle.com` is required on the host where you run Helm.

> [!NOTE]
> For Airgap installations, a connection to the internet on a machine is required to download Develocity installation bundles. You must ensure that you can transfer the files to the host (with limited internet connectivity) at installation time.

Test connectivity by running the following commands:

```shell
curl -sw \\n --fail-with-body --show-error https://helm.gradle.com/ping
```

```shell
kubectl run gradle-registry-test -q --rm --attach --restart=Never \
  --image=curlimages/curl -- -sw \\n --fail-with-body --show-error \
  https://registry.gradle.com/ping
```

```shell
kubectl run gradle-harbor-test -q --rm --attach --restart=Never \
  --image=curlimages/curl -- -sw \\n --fail-with-body --show-error \
  https://harbor.gradle.com/ping
```

All three of these commands should return `SUCCESS`.

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

#### HTTP / HTTPS

Connecting to the application over **HTTPS with a trusted certificate** is strongly recommended.

<a id="https_using_ingress"></a>

When using the Develocity supplied Ingress, HTTPS is enabled by default with a self-signed certificate.

Your organization must provide the SSL certificates to Helm, trusted or untrusted.

Where a reverse proxy or load balancer performs SSL termination, configure the SSL certificates with that infrastructure instead.

<a id="ports"></a>

#### Ports

You can change the ports the application accepts traffic on from the default of 443, or 80 for plain HTTP, during [Helm Configuration](#helm_config).

Make sure any additional ports such as user-managed database or object-storage ports are reachable if necessary.

<a id="proxy_configuration"></a>

#### Proxy

If your organization requires all outbound HTTP traffic to go through an HTTP proxy, configure that during [Helm Configuration](#helm_config).

<a id="hostname"></a>

#### Hostname

When installing Develocity, a hostname such as `develocity.example.com` is required.

Make sure to configure the DNS records accordingly.

Add an `A` record for the hostname that points to the public IP address of your host.

```
develocity.example.com A 12.34.56.78
```

Verify that your DNS record works before installing Develocity by running `dig develocity.example.com` or `ping develocity.example.com` within the terminal.

> [!TIP]
> If running Develocity behind a cloud load balancer, use `/ping` for the load balancer’s health check. It will respond as healthy when Develocity is capable of handling requests. Using the load balancer to manage fail-over might be undesirable for highly available installations.

If you are installing Develocity in a highly available setup, submit a ticket at [support.gradle.com](https://support.gradle.com/hc/requests/new) for assistance.

<a id="pod-to-pod-communication"></a>

#### Pod to Pod Communication

Develocity does not provide a mechanism to encrypt communication between components of its system. If your system requires that, delegate it to your infrastructure using tools such as a [Kubernetes CNI](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) or a Service Mesh of your choice.

<a id="kubernetes_permissions"></a>

### Kubernetes Permissions

The user running Helm or applying its output should have permission to create Kubernetes resources in the designated namespace.

If your Kubernetes environment has fine-grained permissions such that your Kubernetes account might not be able to create certain types of resources, inspect the resources that Develocity creates by running [`helm template`](#run_helm_template) and viewing the output.

<a id="helm_config"></a>

## Helm Configuration

<a id="values_yaml"></a>

A Helm values file holds the installation options for Develocity.

**Follow the instructions in the [Kubernetes Helm Chart Configuration Guide](https://docs.develocity.ai/2026.3/reference/helm-charts/cluster/) and return to this document with a complete `values.yaml` file.**

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

## Installation

Run the following commands on a host with connectivity to your Kubernetes cluster.

**If you are installing Develocity on a host without public network connectivity, follow the [Airgap installation instructions](#airgap_install).**

<a id="online_helm_installation"></a>

### Install Helm

Develocity requires **Helm version 3.13.x (or later)** to install.

It’s recommended to use the latest version available as this will have all known security vulnerabilities addressed. [This document](https://helm.sh/docs/topics/version_skew/) describes the maximum version skew supported between Helm and Kubernetes.

> [!TIP]
> For more information on installing Helm (including alternate installation approaches), see [Installing Helm](https://helm.sh/docs/intro/install/).

Install Helm with the following command:

```shell
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
```

<a id="repo"></a>

### Install the Helm Chart

Develocity is distributed from the [Develocity Helm repository](https://helm.gradle.com/).

Add the Develocity Helm repository to your Helm installation and fetch its contents into the local cache:

```shell
helm repo add gradle https://helm.gradle.com/
```

```shell
helm repo update gradle
```

Verify that the Develocity chart is accessible:

```shell
helm search repo gradle-enterprise
```

This will report the latest versions available for the two Develocity charts:

**Output:**

```
NAME                                CHART VERSION       APP VERSION         DESCRIPTION
gradle/gradle-enterprise            2026.3.0            2026.3.0            Official Develocity chart for Kubernetes cluster installations
gradle/gradle-enterprise-standalone	2026.3.0            2026.3.0            Official Develocity chart for standalone installations
```

<a id="install"></a>

### Install Develocity

Install Develocity by running:

```shell
helm install \
  --create-namespace --namespace develocity \(1)
  ge \(2)
  gradle/gradle-enterprise \(3)
  --values values.yaml \(4)
  --set-file global.license.file=./develocity.license (5)
```

1. This example uses develocity as the namespace, but it can be a custom name. If you use a custom name, update all other example commands accordingly.
2. This is the Helm release name. Helm uses it to identify the Develocity installation.
3. The Develocity chart to install, in this case, gradle/gradle-enterprise.To install a specific version, use --version 2026.3.0.
4. The Helm values file with configuration values, including items such as the hostname.
5. The Develocity license file (if not already included in values file).

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

### Start Develocity

Check that the Helm release is installed:

```shell
helm --namespace develocity list
```

**Output:**

```
NAME      NAMESPACE     REVISION    UPDATED            STATUS      CHART      APP VERSION
ge        develocity    1           2026-09-24         deployed    2026.3.0   2026.3.0
```

You can inspect the status of the Develocity Pods:

```shell
kubectl --namespace develocity get pods
```

**Output:**

```
NAME                                               READY   STATUS    RESTARTS   AGE
edge-node-7d9c8b6f4d-x2kfp                         1/1     Running   0          4m41s
gradle-database-5f9ddc958b-pn8wm                   3/3     Running   0          4m41s
gradle-embedded-object-storage-86745c9cd7-2lpb9    1/1     Running   0          4m41s
gradle-enterprise-app-58b7b75579-4c5hz             1/1     Running   0          4m41s
gradle-enterprise-operator-bdb9b67bc-5m9wb         1/1     Running   0          4m41s
gradle-keycloak-64cd768b89-rk9g2                   1/1     Running   1          4m41s
gradle-monitoring-849994bb56-4wr9t                 5/5     Running   0          4m41s
gradle-proxy-6d7b965c4f-b6jdb                      1/1     Running   0          4m41s
gradle-test-distribution-broker-5494796d9b-gb289   1/1     Running   0          4m41s
```

The `edge-node` Pod is the co-located [Edge](https://docs.develocity.ai/2026.3/administration/build-acceleration/edge/) node, which Develocity deploys by default to provide a local cache layer. To scale or resize it, see the [Edge Node](https://docs.develocity.ai/2026.3/reference/helm-charts/cluster/#edge_node) Helm configuration.

Use the Develocity `/ping` endpoint to verify network connectivity.

Run the following command on any machine that needs to connect to Develocity:

```shell
curl -sw \\n --fail-with-body --show-error https://«develocity-host»/ping
```

The command returns `{"status":"UP"}` as the response message.

Once all Pods have a status of `Running` and the system is up and connected, you can interact with Develocity in a web browser. Its URL is the hostname you configured for the installation.

![Develocity Sign in Page of Your Instance](https://docs.develocity.ai/2026.3/installation/kubernetes-installation/../_images/gradle-enterprise.png)

Develocity Sign in Page of Your Instance

**Develocity is now installed and running.**

See [Next Steps](#next_steps) to learn more about Develocity.

<a id="airgap_install"></a>

## Airgap Installation

Airgap installations **require a Docker or compatible registry available on an internal network that is accessible from the cluster** to which Develocity images can be pushed.

Airgap installations **require a specific entitlement on your license**. To enable it, contact [Develocity support](https://support.gradle.com/) or your customer representative.

For Airgap installations:

*   Download the installation files on a host with access to the internet
    
*   Upload the images to the internal container registry, from a host with network access to that registry (no internet access required)
    
*   Run Helm on a host with network access to the Kubernetes cluster (no internet access required)
    
*   Provide some mechanism for transferring the downloaded installation files to where you need them
    

<a id="overview"></a>

### Overview

In an airgap installation, the container images are preloaded into K3s. Helm is then configured so that no attempt is made to pull images from the outside world.

Airgap installations require a specific entitlement on your license. Please contact Gradle if you need an Airgap-enabled license.

Airgap installation involves downloading files, transferring them, installing supporting software, and running `helm install`.

> [!NOTE]
> When installing Develocity, follow the installation manual for that version as the steps may have changed. See [Develocity releases](https://develocity.ai/releases/) for information about the available versions.

We recommend you save all the files into a single **transfer directory**, so that it’s effortless to transfer to the host where you are installing Develocity. For example:

```shell
mkdir develocity-files && cd develocity-files
```

<a id="download-helm"></a>

### Download Helm

Use the [compatibility matrix](https://docs.develocity.ai/2026.3/miscellaneous/compatibility/#kubernetes_and_helm) to identify the latest version of Helm supported by your version of Develocity.

Download the Helm binary:

```shell
curl -L -o helm-linux-amd64.tar.gz https://get.helm.sh/helm-v4.3.0-linux-amd64.tar.gz
```

> [!NOTE]
> You can see all compatible Helm releases on the Helm [releases page](https://github.com/helm/helm/releases).

<a id="airgap_bundle_download"></a>

### Download Bundle

Save your Develocity license to the transfer directory as `develocity.license`.

Download and verify the airgap bundle:

```shell
curl -LOJd @develocity.license \
  https://registry.gradle.com/airgap/gradle-enterprise-2026.3.0-bundle.tar.gz
```

```shell
curl -LOJd @develocity.license \
  https://registry.gradle.com/airgap/gradle-enterprise-2026.3.0-bundle.tar.gz.sha256
```

```shell
sha256sum -c gradle-enterprise-2026.3.0-bundle.tar.gz.sha256
```

If the checksum verification fails, check the contents of the downloaded files for error messages.  
If the error message indicates that your license is invalid/expired/not airgap enabled, you will need to request an updated license file by contacting your customer success representative.

> [!TIP]
> Instead of running the above `curl` commands, you can download the airgap bundle by navigating to [https://registry.gradle.com/airgap](https://registry.gradle.com/airgap) in your browser and following the instructions on the page.

<a id="airgap_values_yaml_download"></a>

### Download Helm Values File

Download and verify the example Helm values file:

```shell
curl -L -o example.values.yaml \
  https://docs.develocity.ai/downloads/gradle-enterprise-values/gradle-enterprise-values-2026.3.0.yaml
```

```shell
curl -L -o example.values.yaml.sha256 \
  https://docs.develocity.ai/downloads/gradle-enterprise-values/gradle-enterprise-values-2026.3.0.yaml.asc.sha256
```

```shell
echo "$(cat example.values.yaml.sha256)  example.values.yaml" | sha256sum -c -
```

<a id="airgap_values_yaml_configure"></a>

### Configure Helm Values File

Before installing Develocity and its prerequisites, make sure your Helm values file from the [Helm Configuration](#helm_config) section is available on your local workstation.

You can use the example `values.yaml` file from the earlier section to check for any missing configuration.

<a id="transfer-files"></a>

### Transfer Files

Check that the transfer directory has the following files (additional files are fine):

*   `helm-linux-amd64.tar.gz`
    
*   `develocity.license`
    
*   `values.yaml`
    
*   `gradle-enterprise-2026.3.0-bundle.tar.gz`
    
*   Optional: SSL certificates
    

After verifying that all the required files are present, transfer them to the host where you are installing Develocity.

<a id="airgap_image_upload"></a>

### Upload Images

Follow these instructions on the host with connectivity to the internal container registry with your transferred files present in the current directory.

> [!NOTE]
> You must be logged in to the registry before running these commands.

Expand the bundle and upload the images to the internal container registry:

```shell
tar zxvf gradle-enterprise-2026.3.0-bundle.tar.gz
./upload-images.sh --registry=registry.example.com/gradle-enterprise
```

<a id="airgap_helm_installation"></a>

### Install Helm

Run these steps on the host with connectivity to the Kubernetes cluster, with the transferred files in the current directory.

To install Helm:

```shell
tar -zxvf helm-linux-amd64.tar.gz && sudo mv linux-amd64/helm /usr/local/bin/helm
```

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

### Install Develocity

The recommended way to install Develocity is letting Helm manage the installation.

Follow these instructions on the host with connectivity to the Kubernetes cluster with your transferred files present in the current directory.

Expand the bundle (may have already been expanded if you uploaded the images on this host):

```shell
tar zxvf gradle-enterprise-2026.3.0-bundle.tar.gz
```

Install Develocity:

```shell
helm install \
  --create-namespace --namespace develocity \(1)
  ge \(2)
  ./gradle-enterprise-2026.3.0.tgz \(3)
  --values values.yaml \(4)
  --set-file global.license.file=./develocity.license (5)
```

1. This example uses develocity as the namespace, but it can be a custom name. If you use a custom name, update all other example commands accordingly. Running with --create-namespace will create the namespace if it doesn’t already exist.The namespace option may not be required for OpenShift if oc login has been run and the active project for the current context is set.
2. This is the Helm release name. It’s used by Helm to identify the Develocity installation.
3. The Develocity chart to install. This is the .tgz file included in the airgap bundle.
4. The Helm values file with configuration values, including items such as the hostname.
5. The Develocity license file (if not already included in values file).

<a id="start_gradle"></a>

### Start Develocity

You can see the status of Develocity starting up by examining its Pods.

```shell
kubectl --namespace develocity get pods
```

**Output:**

```
NAME                                              READY   STATUS              RESTARTS   AGE
edge-node-7d9c8b6f4d-x2kfp                         0/1     ContainerCreating   0            4s
gradle-database-5f9ddc958b-pn8wm                   0/3     Init:0/3            0            4s
gradle-embedded-object-storage-86745c9cd7-2lpb9    0/1     ContainerCreating   0            4s
gradle-enterprise-app-58b7b75579-4c5hz             0/1     Init:0/4            0            4s
gradle-enterprise-operator-bdb9b67bc-5m9wb         0/1     ContainerCreating   0            4s
gradle-keycloak-64cd768b89-rk9g2                   0/1     Init:0/1            1            4s
gradle-monitoring-849994bb56-4wr9t                 0/5     ContainerCreating   0            3s
gradle-proxy-6d7b965c4f-b6jdb                      0/1     ContainerCreating   0            3s
gradle-test-distribution-broker-5494796d9b-gb289   0/1     Init:0/1            0            3s
```

The Pods should all report `Running` once startup completes:

```shell
kubectl --namespace develocity get pods
```

**Output:**

```
NAME                                               READY   STATUS    RESTARTS   AGE
edge-node-7d9c8b6f4d-x2kfp                         1/1     Running   0          4m41s
gradle-database-5f9ddc958b-pn8wm                   3/3     Running   0          4m41s
gradle-embedded-object-storage-86745c9cd7-2lpb9    1/1     Running   0          4m41s
gradle-enterprise-app-58b7b75579-4c5hz             1/1     Running   0          4m41s
gradle-enterprise-operator-bdb9b67bc-5m9wb         1/1     Running   0          4m41s
gradle-keycloak-64cd768b89-rk9g2                   1/1     Running   1          4m41s
gradle-monitoring-849994bb56-4wr9t                 5/5     Running   0          4m41s
gradle-proxy-6d7b965c4f-b6jdb                      1/1     Running   0          4m41s
gradle-test-distribution-broker-5494796d9b-gb289   1/1     Running   0          4m41s
```

Once all Pods have a status of `Running` and the system is up and connected, you can interact with Develocity in a web browser. Its URL is the hostname you configured for the installation.

<a id="cleanup"></a>

### Cleanup

The files used during installation are not required at runtime. Remove the following after installation:

*   `helm-linux-amd64.tar.gz`
    
*   `gradle-enterprise-2026.3.0-bundle.tar.gz`
    
*   `gradle-enterprise-2026.3.0.tgz`
    
*   `gradle-enterprise-2026.3.0-images.tar`
    

Keep these files, which you might need for future upgrades or maintenance:

*   Helm values files
    
*   SSL certificates
    
*   Develocity license
    

> [!WARNING]
> Treat these files as sensitive.

**Develocity is now installed and running.**

<a id="next_steps"></a>

## Next Steps

*   [Sign in as the System User](https://docs.develocity.ai/2026.3/administration/access-control/system-user/): Set the system user password and create a personal administrator account.
    
*   [Publish Your First Build Scan](https://docs.develocity.ai/2026.3/using-develocity/build-scan/): Validate your installation end-to-end from Gradle, Maven, sbt, Bazel, or npm.
    
*   [Kubernetes Helm Chart Configuration Guide](https://docs.develocity.ai/2026.3/reference/helm-charts/cluster/): Develocity Helm chart options.
    
*   [Develocity Administration](https://docs.develocity.ai/2026.3/administration/): Learn how to configure and administer Develocity.
    
*   [DPE University](https://dpeuniversity.gradle.com/app/catalog?product=Develocity): A free, self-paced training portal to get the most out of Develocity.
    

<a id="advanced_installation"></a>

## Appendix A: Advanced Installation

<a id="chart-download-and-selection-options"></a>

### Chart Download and Selection Options

When asking Helm to install or process a chart, you can pick from several sources:

*   A chart from a repository directly.
    
*   A downloaded chart archive.
    
*   An expanded chart directory.
    

Which of these to use depends somewhat on network and policy requirements.

<a id="direct-selection"></a>

#### Direct Selection

This involves running `helm` commands using the above `gradle/gradle-enterprise` chart name. Helm downloads the chart if necessary, so this option requires internet connectivity on the host that runs Helm.

Examples:

```shell
helm install ge gradle/gradle-enterprise «options»
```

```shell
helm template gradle/gradle-enterprise «options»
```

Unless you have a reason not to, install Develocity charts this way. The main installation section above uses this method.

<a id="downloaded-archive"></a>

#### Downloaded Archive

Helm can download a chart archive, and can run using the downloaded archive. This is most useful when the host with internet connectivity does not have access to the Kubernetes cluster.

Example:

```shell
helm pull gradle/gradle-enterprise
```

Downloads the latest version to an archive in the current directory for example, `gradle-enterprise-2026.3.0.tgz`.

Then later, possibly on a different host:

```shell
helm install ge gradle-enterprise-2026.3.0.tgz «options»
```

This is also the installation method used for airgap installations.

<a id="expanded-chart-directory"></a>

#### Expanded Chart Directory

Helm users commonly download a chart, edit the included Helm values file, and then commit the result to source control. Keep configuration in a separate values file instead, and install a pristine Develocity chart with the configuration provided alongside. If your organization’s processes expect Helm Charts to be edited inline, use this method.

Example:

```shell
helm pull gradle/gradle-enterprise --untar
```

Downloads the latest version, and expands it into a `gradle-enterprise` directory in the current directory.

Or for airgap customers, extract the chart `.tgz` file included in the bundle:

```shell
mkdir -p gradle-enterprise && \
  tar zxvf path/to/gradle-enterprise-2026.3.0.tgz -C gradle-enterprise
```

At this point you can edit `gradle-enterprise/values.yaml` and commit the directory to source control.

Later:

```shell
helm install ge ./gradle-enterprise «options»
```

Installs Develocity from a directory with the expanded chart.

<a id="helm_post_processing"></a>

### Helm Post-Processing

Many organizations need to customize Kubernetes manifests before applying them to their cluster. [Kustomize](https://kustomize.io/) is one commonly used tool for this. You can alter the Helm-generated Kubernetes manifests before Helm applies them to the cluster, using [Helm Post Rendering](https://helm.sh/docs/topics/advanced/#post-rendering) via the `--post-renderer` flag. Helm still manages what reaches the cluster, so you keep both the customization and the release tracking.

```shell
helm install \
  --create-namespace --namespace develocity \
  ge gradle/gradle-enterprise \
  --values values.yaml \
  --set-file global.license.file=./develocity.license \
  --post-renderer path/to/post-renderer.sh
```

The `--post-renderer` option specifies an executable script that takes the Helm-rendered manifests as input on stdin, and produces manifests with further customizations as output on stdout.

The following example is a Helm post-renderer that uses Kustomize:

```shell
#!/usr/bin/env bash
set -eo pipefail
cat <&0 > /absolute/path/to/kustomizations/develocity.yaml
kustomize build /absolute/path/to/kustomizations
```

In this example, the `develocity.yaml` file contains the output of the Helm rendering step. The `kustomization.yaml` then takes this file as an input:

```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - develocity.yaml

# Rest of kustomization
```

<a id="user_managed_installation"></a>

### User-Managed Installation

An alternative to running `helm install` directly on your cluster is to have Helm generate Kubernetes manifests that you then apply with `kubectl` or other Kubernetes tools. In this mode, Helm does not track installed versions: the resources in the cluster are untracked, and Helm cannot report which version is installed.

The most common reasons to do a user-managed installation are:

*   Requirements that the final applied manifests are committed to source control.
    
*   Need to modify the manifests before applying them to the cluster in a way that [Helm post-processing](#helm_post_processing) does not support.
    
*   Preference or policy to have manifests applied and managed by other tools.
    
*   Need to run Helm on a host separated from the cluster.
    

There are some other downsides:

*   You must clean up some resources by hand after [upgrades](https://docs.develocity.ai/2026.3/operations/upgrade/) or [uninstallation](https://docs.develocity.ai/2026.3/operations/uninstall/).
    

<a id="run_helm_template"></a>

#### Running `helm template`

By default, Helm will generate a combined Kubernetes manifest and write it to standard output.

```shell
helm template \
  gradle/gradle-enterprise \(1)
  --values values.yaml \(2)
  --set-file global.license.file=./develocity.license \(3)
  > develocity.yaml (4)
```

1. The Develocity chart to install, gradle/gradle-enterprise.To install a specific version, pass this as additional parameters, for example, --version 2026.3.0.
2. The Helm values file with configuration values, including items such as the hostname.
3. The Develocity license file.
4. Save all the rendered manifests to a single YAML file.

You might want to pass other files using `--set-file`, such as certificates for HTTPS.

Configuration values can be provided to Helm in a variety of ways. This includes:

*   Providing a Helm values file (which can contain inline files) with `--values`
    
*   Providing files (such as the Develocity license or certificates) with `--set-file`
    
*   Setting individual values with `--set`
    

Choose a combination that works for your own configuration management processes.

You can commit the generated manifest to version control, copy it, or process it further at this point.

Helm can also write the manifests as a set of files in a directory, broken up into logical groupings, using the `--output-dir` argument:

```shell
helm template \
  gradle/gradle-enterprise \
  --values values.yaml \
  --set-file global.license.file=./develocity.license \
  --output-dir ./my-develocity-manifests
```

The above will create files under the specified directory. This might be a preferred form for customization, including using tools such as [Kustomize](https://kustomize.io/).

<a id="extracting-ingress-rules"></a>

#### Extracting Ingress Rules

You might route Develocity’s traffic through your own controller or gateway rather than the supplied Ingress. In that case, render the chart’s Ingress resources and use them as the authoritative source for the routes to replicate.

The rendered output reflects the exact paths for the chart version you render, including routes added in newer releases such as the co-located Edge node routes. This gives you a version-accurate reference for building your own routing configuration.

Render the chart and filter the output to the `Ingress` resources with [yq](https://mikefarah.gitbook.io/yq/):

```shell
helm template ge gradle/gradle-enterprise \(1)
  --version 2026.3.0 \(2)
  --values values.yaml \(3)
  --set-file global.license.file=./develocity.license \
  | yq 'select(.kind == "Ingress")' (4)
```

1. The Develocity chart to render.
2. The chart version to render.Change this value to extract the rules for any released version.
3. Reuse the same values file you deploy with, so the rendered hostnames and paths match your installation.
4. Keep only the Ingress documents from the combined manifest.

`helm template` fails when required values, such as the hostname or license, are missing.

<a id="invariant_output"></a>

#### Invariant Output

By default, the Develocity Helm Chart randomly generates several secrets during rendering. For example, the embedded database user credentials. As a security precaution, those secrets differ each time, so repeated runs of `helm template` produce non-identical manifests. That causes unnecessary restarts where automated tools use changes in rendering output to trigger redeployment.

You can configure Helm so that the output of `helm template` is invariant. Set the secret values directly, or specify a user-managed secret. You also can combine the two solutions if appropriate for your installation, by specifying some secret values directly, and some using user-managed secrets.

The table below lists the secrets you need to specify to get invariant output.

  
| Helm value | Secret data key(s) | Usage |
| --- | --- | --- |
| For these Helm value keys, use `secretName` under the key to reference a user-managed secret, or set the secret directly. Single-value secrets take a `value` sub-key. Secrets with named data keys take the key shown in the next column directly, for example `password`. | When creating user-managed secrets, the secret should have the verbatim data key(s) given in this column. Dots (.) do not indicate nesting or indentation. For example, a secret data key such as 'abc.def' should appear in your created secret as follows: |  |
| `database.credentials.app` | `username`, `password` | The credentials used by the app to connect to the database username must be set to ge\_app |
| `database.credentials.migrator` | `username`, `password` | The credentials used when running database migrations username must be set to ge\_migrator |
| `database.credentials.monitor` | `username`, `password` | The credentials used to monitor the database username must be set to ge\_monitor |
| `enterprise.session.key` | `client.side.session.key` | The symmetric encryption key used for client-side session data |
| `enterprise.session.token` | `client.side.session.token` | The token used for signing the data associated with client sessions |
| `authenticationBroker.clientSecret` | `keycloak.client.secret` | The client secret used by the app when connecting to Keycloak |
| `authenticationBroker.adminPassword` | `keycloak.admin.password` | The password for the keycloak admin user |
| `objectStorage.embedded.credentials.app` | `password` | The password used by the app to connect to the embedded object store. |
| `objectStorage.embedded.credentials.migrator` | `password` | The password used by the app to migrate data in the embedded object store. |
| `objectStorage.embedded.credentials.superuser` | `user`, `password` | The credentials used by the app to create and configure the embedded object store. **`user` must be set to `gradle-embedded-object-storage-root-user`** |
| `objectStorage.embedded.credentials.monitoring.password` | `password` | The password used by the internal monitoring stack to store and retrieve `metrics` and `logs` |
| `global.managementApiToken` | `token` | The token authorizing privileged management requests on internal endpoints, used by develocityctl and support-bundle collection. If you set neither value nor secretName, Develocity generates the token for you. |
| `global.managementApiToken` | `token` | The token authorizing privileged management requests on internal endpoints, used by develocityctl and support-bundle collection. If you set neither value nor secretName, Develocity generates the token for you. |
| `edgeNode.registrationKey` | `key` | The registration key used by edge nodes to authenticate with Develocity |
| `unattended.configuration.systemPassword` | None. Must be provided via unattended configuration. | The hash of the system user password. If not specified, then `gradle-default-system-password-secret` is generated. |

Below shows an example Helm values YAML you can use to get invariant output by specifying user-managed secrets.

**values.yaml:**

```
global:
  managementApiToken:
    secretName: <user-managed kubernetes secret resource name>
  unattended:
    configuration:
      version: 17
      systemPassword: "«hashed-system-password»"

database:
  credentials:
    app:
      secretName: <user-managed kubernetes secret resource name>
    migrator:
      secretName: <user-managed kubernetes secret resource name>
    monitor:
      secretName: <user-managed kubernetes secret resource name>

enterprise:
  session:
    key:
      secretName: <user-managed kubernetes secret resource name>
    token:
      secretName: <user-managed kubernetes secret resource name>

authenticationBroker:
  clientSecret:
    secretName: <user-managed kubernetes secret resource name>
  adminPassword:
    secretName: <user-managed kubernetes secret resource name>

objectStorage:
  embedded:
    credentials:
      app:
        secretName: <user-managed kubernetes secret resource name>
      migrator:
        secretName: <user-managed kubernetes secret resource name>
      monitoring:
        secretName: <user-managed kubernetes secret resource name>
      superuser:
        secretName: <user-managed kubernetes secret resource name>

edgeNode:
  registrationKey:
    secretName: <user-managed kubernetes secret resource name>
```

To get invariant output by specifying secret values directly in your Helm `values.yaml`:

```yaml
global:
  managementApiToken:
    value: <secret value>
  unattended:
    configuration:
      version: 17
      systemPassword: "«hashed-system-password»"

database:
  credentials:
    app:
      password: <secret value>
    migrator:
      password: <secret value>
    monitor:
      password: <secret value>

enterprise:
  session:
    key:
      value: <secret value>
    token:
      value: <secret value>

authenticationBroker:
  clientSecret:
    value: <secret value>
  adminPassword:
    value: <secret value>

objectStorage:
  embedded:
    credentials:
      app:
        password: <secret value>
      migrator:
        password: <secret value>
      monitoring:
        password: <secret value>
      superuser:
        password: <secret value>

edgeNode:
  registrationKey:
    value: <secret value>
```

As with other values, you can also set these by passing `--set` or `--set-file` to Helm.

The following example uses `kubectl` to create the `db-app-user-credentials`, `db-migrator-user-credentials`, and `embedded-object-storage-superuser-credentials` secrets in the `develocity` namespace:

```shell
# Add this to your `helm install` command: `--set database.credentials.app.secretName=db-app-user-credentials`
kubectl -n develocity create secret generic db-app-user-credentials --from-literal=username=ge_app --from-literal=password=<your password here>

# Add this to your `helm install` command: `--set database.credentials.migrator.secretName=db-migrator-user-credentials`
kubectl -n develocity create secret generic db-migrator-user-credentials --from-literal=username=ge_migrator --from-literal=password=<your password here>

# Add this to your `helm install` command: `--set objectStorage.embedded.credentials.superuser.secretName=embedded-object-storage-superuser-credentials`
kubectl -n develocity create secret generic embedded-object-storage-superuser-credentials --from-literal=user=gradle-embedded-object-storage-root-user --from-literal=password=<your password here>
```

> [!NOTE]
> When you create a secret and reference it by name in your Develocity installation (for example, using a `secretName` value), Helm does not manage that secret. If you change the secret value, for example when periodically cycling a password, restart Develocity manually so the change takes effect. To do this, restart all the Pods in the Develocity Helm installation.

<a id="mirroring_the_helm_charts"></a>

### Mirroring the Helm Charts

You can mirror the Develocity Helm Charts in an internal Helm Chart repository.

Using `helm pull` to fetch the charts is the recommended approach since the Develocity Helm repository index uses relative URLs.

```shell
helm search repo gradle-enterprise --versions --output json | jq -r '"helm pull " + .[].name + " --version " + .[].version' | sort | uniq | bash
```

<a id="uninstall"></a>

## Uninstalling Develocity

To uninstall Develocity, follow the [Uninstall Guide](https://docs.develocity.ai/2026.3/operations/uninstall/).