> For the complete documentation index, see [llms.txt](https://docs.sonarsource.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sonarsource.com/sonarqube-server/server-installation/on-kubernetes-or-openshift/customizing-helm-chart.md).

# Customizing Helm chart

How to perform the most important SonarQube Helm chart customization when working with SonarQube Server 2026.5.

While we only document the most pressing SonarQube Server Helm chart customizations in this documentation, there are other possibilities for you to choose to customize the chart before installing. Please see the [Helm chart README file](https://artifacthub.io/packages/helm/sonarqube/sonarqube) for more information about these options. In particular, see the recommended production use case values.

You can customize the SonarQube Server Helm chart:

* By editing the default values in the `values.yaml` file.
* Or directly in the Helm chart installation command line, see [Installing Helm chart](/sonarqube-server/server-installation/on-kubernetes-or-openshift/installing-helm-chart.md).

Parameters passed in the command line have precedence over parameters set in `values.yaml`.

{% hint style="info" %}
To set up SonarQube Server monitoring, see [Setting up monitoring](/sonarqube-server/server-installation/on-kubernetes-or-openshift/set-up-monitoring.md).
{% endhint %}

## Enabling OpenShift <a href="#enabling-openshift" id="enabling-openshift"></a>

If you want to install SonarQube Server on OpenShift, you must enable OpenShift in the Helm chart. In that case:

* The Helm chart will auto-configure itself to comply with the default OpenShift [SCCs](https://docs.openshift.com/container-platform/3.11/admin_guide/manage_scc.html) (Security Context Constraints).
* Not using a default SCC in your OpenShift cluster may cause problems.

To enable OpenShift in the Helm chart:

1. Set `OpenShift.enabled` to `true`.
2. Set `OpenShift.createSCC` to `false`.
3. If you want to make your application publicly visible with Routes, you can set `route.enabled` to `true`. Please check the [configuration details](https://artifacthub.io/packages/helm/sonarqube/sonarqube#openshift) in the Helm chart documentation to customize the Route based on your needs.

## Ensuring a restricted security level <a href="#ensuring-restricted-level" id="ensuring-restricted-level"></a>

<details>

<summary>About the Pod security level</summary>

The table below shows the [Pod security level](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-levels) applied by default to each container. The SonarQube Server Helm chart enforces each level through a default `SecurityContext`.

| **Container**                           | **Pod security level** | **Note**                                                                                                                 |
| --------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| SonarQube Server application containers | restricted             | <p><br></p>                                                                                                              |
| SonarQube Server init containers        | restricted             | <p><br></p>                                                                                                              |
| init-sysctl                             | privileged             | <p>Utility software that requires root access.</p><p><br></p>                                                            |
| init-fs                                 | baseline               | Utility software that requires root access. To disable the container, set `initFs.enabled` in the Helm chart to `false`. |

The `SecurityContext` below is set as default on all restricted containers.

```css-79elbk
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
  type: RuntimeDefault
capabilities:
  drop: ["ALL"]
```

</details>

<details>

<summary>In a Kubernetes installation</summary>

To run the SonarQube Server Helm chart in a full restricted namespace, you must disable the `init-sysctl` and `init-fs` containers by setting in the Helm chart:

* `initSysctl.enabled` to `false`.
* `initFs.enabled` to `false`.

These containers apply settings at the host/kernel level therefore disabling them may require additional configuration steps. For more information, see [Elasticsearch prerequisites](https://artifacthub.io/packages/helm/sonarqube/sonarqube#elasticsearch-prerequisites) in the Helm chart documentation.

</details>

<details>

<summary>In an OpenShift installation</summary>

The configuration described in [#enabling-openshift](#enabling-openshift "mention") above forces the disabling of the `init-sysctl` and `init-fs` containers. These containers should not be required in the vast majority of cases for an Openshift installation. Therefore, an Openshift installation is compatible with restricted SCCv2 (Security Context Constraints).

</details>

## Setting access to your external database <a href="#access-to-database" id="access-to-database"></a>

You must configure the access to your database (except if you want to use SonarQube for test purposes and want to use the embedded database H2).

To do so:

1. Set `jdbcOverwrite.enabled` to `true`.
2. Set `jdbcOverwrite.jdbcUrl` to the database URL and `jdbcOverwrite.jdbcUsername` to the database username.
3. Store the database password in a Kubernetes secret and set `jdbcOverwrite.jdbcSecretName` to the secret’s name.
4. If you use an Oracle database:
   * Let the Helm chart download and inject the corresponding JDBC driver in SonarQube by setting `jdbcOverwrite.oracleJdbcDriver.url` to the URL of the Oracle JDBC driver to be downloaded.
   * In case the download requires it, set `jdbcOverwrite.oracleJdbcDriver.netrcCreds` to the name of the Kubernetes secret containing the `.netrc` file that stores the credentials.

For more information, see this [section](https://artifacthub.io/packages/helm/sonarqube/sonarqube#jdbc-overwrite) in the ArtifactHub page of the Helm Chart.

## Storing sensitive properties in a secret <a href="#sonar-secret-properties" id="sonar-secret-properties"></a>

To keep sensitive SonarQube Server properties out of `values.yaml`, store them in a Kubernetes secret and reference the secret with `sonarSecretProperties`:

1. Create a `secret.properties` file with one property per line, for example:

   ```properties
   sonar.auth.jwtBase64Hs256Secret=<value>
   ```
2. Create a secret with the key `secret.properties`:

   ```bash
   kubectl -n <namespace> create secret generic <secretName> --from-file=secret.properties=secret.properties
   ```
3. In `values.yaml`, set `sonarSecretProperties` to the secret's name.

## Installing plugins <a href="#installing-plugins" id="installing-plugins"></a>

To install plugins, set `plugins.install` to a list of plugin download URLs. The chart downloads the plugins at startup, so the pod needs network access to these URLs. See [Installing a plugin](/sonarqube-server/server-installation/plugins/install-a-plugin.md) for an example.

## Enabling persistence in Elasticsearch <a href="#enabling-es-persistency" id="enabling-es-persistency"></a>

SonarQube Server comes with a bundled Elasticsearch and both Elasticsearch and SonarQube Server are stateful. There is an option to persist the Elasticsearch indexes in a Persistent Volume, but with regular stoppage operations by the Kubernetes Cluster, these indexes can be corrupted. By default, persistence is disabled in the Helm chart.

Enabling persistence significantly reduces startup time for the SonarQube Server Pod, but risks corrupting your Elasticsearch index. Enable it by adding the following to the `values.yaml`:

```css-79elbk
persistence:
  enabled: true
```

Leaving persistence disabled results in a longer startup time until SonarQube Server is fully available, but you won’t lose any data as SonarQube Server will persist all data in the database.

## Using custom certificates for your code repository <a href="#custom-certificates" id="custom-certificates"></a>

When you are working with your own certificate authority or in an environment that uses self-signed certificates for your code repository platform, you can create a secret containing this certificate and add this certificate to the Java truststore inside the SonarQube deployment.

To add a certificate to the Javatrustore inside the SonarQube deployment:

1. Ask the relevant team to provide you with a PEM format certificate or certificate chain. We will assume it to be called `cert.pem` on the following commands.
2. Generate the kubernetes secret, e.g. with this command:

```bash
kubectl create secret generic --from-file cert.pem <secretName> -n  <sonarqubeNamespace>
```

The generated secret should then appear in this format and the certificate should contain the full chain:

```yaml
apiVersion: v1
data:
  sonar.crt: <base64 encoded certificate>
kind: Secret
metadata:
  name: <secretName>
  namespace: sq
type: Opaque
```

3\. In SonarQube’s `values.yaml` file, add:

```yaml
caCerts:
  enabled: true
  secret: <secretName>
```

## Proxy configuration <a href="#proxy-configuration" id="proxy-configuration"></a>

You can configure SonarQube Server proxy connection for Helm charts using the following `sonarProperties` in the `values.yaml` file:

* `http.proxyHost`
* `http.proxyPort`
* `http.nonProxyHosts`

For example:

```yaml
sonarProperties:
    http.proxyHost: ‘proxy.company.local‘
    http.proxyPort: ‘8080‘
    http.nonProxyHosts: ‘*.company.local‘
```

The following Helm values only set the corresponding environment variables:

| Property     | Environment variable |
| ------------ | -------------------- |
| `httpProxy`  | `HTTP_PROXY`         |
| `httpsProxy` | `HTTPS_PROXY`        |
| `noProxy`    | `NO_PROXY`           |

See the list of properties for SonarQube Server [List of properties common to all editions](/sonarqube-server/server-installation/system-properties/common-properties.md#proxy-configuration) for more information.

## Making SonarQube Server accessible from outside your cluster <a href="#ingress" id="ingress"></a>

To make SonarQube Server reachable from outside your cluster, you typically need a Gateway API `HTTPRoute` or an Ingress. On OpenShift, you can use a Route instead (see [Enabling OpenShift](#enabling-openshift)). You can also expose the Kubernetes Service directly by setting `service.type` to `LoadBalancer` or `NodePort`, but most production deployments need the routing and TLS termination that an Ingress or `HTTPRoute` provides.

> **Note:** The chart does not bundle an Ingress or Gateway API controller. You need one already running in your cluster, or you need to install one yourself.

Gateway API is the modern successor to Ingress and the standard Kubernetes has settled on.

* We recommend `httproute.enabled` with a [Gateway API](https://gateway-api.sigs.k8s.io/) controller (Istio, Envoy Gateway, GKE Gateway, and so on). See [Creating an HTTPRoute with Gateway API](#httproute-creating). [Migrating from Ingress NGINX to Gateway API](/sonarqube-server/server-installation/on-kubernetes-or-openshift/migrating-from-ingress-nginx-to-gateway-api.md) has a full worked example using Istio, including a comparison table of the two approaches. It applies just as well to a fresh install that chooses Gateway API from day one as it does to a migration.
* If you already run, or prefer, a traditional Ingress controller (NGINX, Traefik, HAProxy, and so on), use `ingress.enabled` instead. If you don’t already have one running, you’re responsible for installing and managing it yourself. The chart does not provide one. See [Creating an Ingress](#ingress-creating).

### Creating an HTTPRoute with Gateway API <a href="#httproute-creating" id="httproute-creating"></a>

This section assumes a [Gateway API](https://gateway-api.sigs.k8s.io/) controller, for example Istio, is already installed in your cluster, along with a `Gateway` resource. For how to install the Gateway API custom resource definitions (CRDs), Istio, and a `Gateway`, see steps 1 through 5 of the *Manual steps* tab in [Migrating from Ingress NGINX to Gateway API](/sonarqube-server/server-installation/on-kubernetes-or-openshift/migrating-from-ingress-nginx-to-gateway-api.md#choose-a-migration-approach). Those steps apply to a fresh install just as well as to a migration.

Once you have a `Gateway`, add the following to your SonarQube Server’s `values.yaml`, then apply it with `helm upgrade` (see [Installing Helm chart](/sonarqube-server/server-installation/on-kubernetes-or-openshift/installing-helm-chart.md)):

```yaml
httproute:
  enabled: true
  gateway: sonarqube-gateway
  gatewayNamespace: sonarqube
  hostnames:
    - sonarqube.your-org.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: <release-name>-sonarqube   # or <release-name>-sonarqube-dce
          port: 9000
```

{% hint style="info" %}
If you leave `httproute.rules` unset, the chart auto-adds a default rule with the correct `backendRefs` for you. As soon as you specify your own `rules`, for example to add a redirect, that default is bypassed, so you must include `backendRefs` yourself.

To find the right Service name for `backendRefs`:

* If you’ve set `fullnameOverride`, use that name instead of `<release-name>-sonarqube`.
* If you’ve set `nameOverride` without `fullnameOverride`, the Service name is `<release-name>-<nameOverride>`.
* Run `kubectl get svc -n <namespace>` to confirm the actual name.
  {% endhint %}

Verify the route:

```bash
kubectl get httproute -n <namespace>
curl -v http://sonarqube.your-org.com/
```

SonarQube Server should return a response. A `404` or `500` response means the route or its backend is misconfigured:

* A `500` response means `backendRefs` points at a Service that does not exist. The Gateway accepts the route, but reports `ResolvedRefs: False` with reason `BackendNotFound`. Run `kubectl describe httproute -n <namespace>` to see it.
* A `404` response means the route has nowhere to send traffic, usually because `backendRefs` is missing altogether.

### Creating an Ingress <a href="#ingress-creating" id="ingress-creating"></a>

> **Note:** `ingress.enabled` creates a plain `Ingress` resource for use with your own, self-managed Ingress controller. The chart no longer bundles an Ingress controller. If you’re setting one up fresh, see the [Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) for a list of Ingress controllers you can install and manage yourself. If you’re looking for the NGINX Ingress controller that used to ship with the chart, see [Removal of the bundled Ingress NGINX controller](#ingress-nginx-removed).

To create an Ingress resource through the Helm chart:

* Add the following to your SonarQube Server’s `values.yaml`. In this configuration, we use the Ingress class NGINX with a body size of at least 64MB since this is what we recommend.

```yaml
ingress:
  enabled: true
  # Used to create an Ingress record.
  hosts:
    - name: sonarqube.your-org.com
      # Different clouds or configurations might need /* as the default path
      path: /
      # For additional control over serviceName and servicePort
      # serviceName: someService
      # servicePort: somePort
  annotations: 
    nginx.ingress.kubernetes.io/proxy-body-size: "64m"
```

### Removal of the bundled Ingress NGINX controller <a href="#ingress-nginx-removed" id="ingress-nginx-removed"></a>

Following the retirement of the ingress-nginx controller in November 2025 (with best-effort support ceasing in March 2026), the chart no longer bundles the `ingress-nginx.enabled`/`nginx.enabled` Ingress controller subchart.

If you're using `ingress.enabled` with your own, self-managed Ingress controller, this change doesn't affect you. No migration is needed.

If you're using the bundled `ingress-nginx.enabled`/`nginx.enabled` controller, migrate to the [Gateway API](https://gateway-api.sigs.k8s.io/guides/), which is the modern successor to Ingress and is supported by the chart's `httproute.enabled` values. See [Migrating from Ingress NGINX to Gateway API](/sonarqube-server/server-installation/on-kubernetes-or-openshift/migrating-from-ingress-nginx-to-gateway-api.md) for a full worked example. Alternatively, consult the [Kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) for a list of self-managed Ingress controllers you can use with `ingress.enabled` instead.

## Related pages <a href="#related-pages" id="related-pages"></a>

* [Installation overview](/sonarqube-server/server-installation/on-kubernetes-or-openshift/installation-overview.md)
* [Before you start](/sonarqube-server/server-installation/on-kubernetes-or-openshift/before-you-start.md)
* [Installing Helm chart](/sonarqube-server/server-installation/on-kubernetes-or-openshift/installing-helm-chart.md)
* [Migrating from Ingress NGINX to Gateway API](/sonarqube-server/server-installation/on-kubernetes-or-openshift/migrating-from-ingress-nginx-to-gateway-api.md)
* [Setting up monitoring](/sonarqube-server/server-installation/on-kubernetes-or-openshift/set-up-monitoring.md)
* Installing Data Center Edition on Kubernetes: [Installing on Kubernetes or Openshift](/sonarqube-server/server-installation/data-center-edition/on-kubernetes-or-openshift.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.sonarsource.com/sonarqube-server/server-installation/on-kubernetes-or-openshift/customizing-helm-chart.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
