> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Helm Controller with Git as Source

> Guide to deploy a Helm chart from a Git repository using Flux source and Helm controllers, creating GitRepository and HelmRelease manifests and reconciling them with flux

This guide shows how to deploy a Helm chart with Flux using the Source Controller to fetch a chart from Git, and the Helm Controller to install the chart via a `HelmRelease`. It keeps the same sequence of operations used in the demo and includes exact manifests and commands you can follow.

Overview

1. Ensure the Helm chart is stored in a Git repository (a branch is fine).
2. Create a `GitRepository` source so Flux's source-controller can fetch the repo.
3. Create a `HelmRelease` that references the `GitRepository` and the chart path/version.
4. Optionally provide a `values.yaml` override file when creating the `HelmRelease`.
5. Commit the generated manifests into the repository Flux watches and let Flux reconcile them.

Quick prerequisites

* A Kubernetes cluster with Flux installed (flux CLI available).
* The Helm chart present in a Git repository and reachable via HTTPS or SSH.
* Access to the branch that contains the chart (the demo uses branch `5-demo`).

Repository and branch

* In the demo the repository `bb-app-source` contains a Helm chart on branch `5-demo`.
* Make sure you switch to that branch locally before working with the chart.

Example Chart metadata (Chart.yaml)

```yaml theme={null}
apiVersion: v2
name: block-buster-helm-app
description: A Helm chart for Block Buster App
version: 7.5.0
```

Example default values (values.yaml)

```yaml theme={null}
image:
  repository: siddharth67/block-buster-dev:7.5.0
  pullPolicy: Always
  # Overrides the image tag whose default is the chart appVersion.
  tag: ""

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80
  targetPort: 80

namespace:
  name: demo-app

labels:
  app:
    name: bb-app
    version: 7.x.x
    env: uat
```

Example of a simple Service template (templates/service.yaml)

```yaml theme={null}
apiVersion: v1
kind: Service
metadata:
  name: block-buster-helm-app
  labels:
    app: {{ .Values.labels.app.name }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      nodePort: {{ .Values.service.nodePort }}
      targetPort: {{ .Values.service.targetPort }}
      protocol: TCP
      name: http
  selector:
    app: {{ .Values.labels.app.name }}
    version: {{ .Values.labels.app.version }}
    env: {{ .Values.labels.app.env }}
```

Create a GitRepository source
Represent the Git repository with the Flux `GitRepository` CRD so the source-controller can fetch it:

```yaml theme={null}
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: 5-demo-source-git-helm-bb-app
  namespace: flux-system
spec:
  interval: 1m0s
  ref:
    branch: 5-demo
  url: https://github.com/sidd-harth-2/bb-app-source
```

Create a HelmRelease with the Flux CLI
Flux has `flux create helmrelease` which generates a `HelmRelease` manifest. You can point the chart source to a `GitRepository`. The CLI also accepts a `--values` file which Flux reads locally and embeds into the exported YAML when you use `--export`.

When using `--values` with `flux create helmrelease --export`, Flux reads the values file from the local filesystem where you run the command and embeds those values into the generated HelmRelease YAML. Ensure the path you specify exists locally before running the command.

Example values override file (5-demo-values.yml)

```yaml theme={null}
replicaCount: 2

service:
  type: NodePort
  nodePort: 30005

namespace:
  name: 5-demo

labels:
  app:
    name: block-buster
    version: 7.5.0
    env: dev
```

Generate the HelmRelease manifest (example)

```bash theme={null}
flux create helmrelease 5-demo-helm-release-git-helm-bb-app \
  --chart helm-chart \
  --interval 10s \
  --target-namespace 5-demo \
  --source GitRepository/5-demo-source-git-helm-bb-app \
  --values 5-demo-values.yml \
  --export > 5-demo-helm-release-git-helm-bb-app.yml
```

A generated HelmRelease (simplified)

```yaml theme={null}
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: 5-demo-helm-release-git-helm-bb-app
  namespace: flux-system
spec:
  chart:
    spec:
      chart: helm-chart
      reconcileStrategy: ChartVersion
      sourceRef:
        kind: GitRepository
        name: 5-demo-source-git-helm-bb-app
  interval: 10s
  targetNamespace: 5-demo
  values:
    labels:
      app:
        env: dev
        name: block-buster
        version: 7.5.0
```

Commit the generated HelmRelease YAML into the repository watched by Flux (for example, the cluster's flux repo) and push. Flux will reconcile the `GitRepository` and `HelmRelease`.

Inspect reconciliation with Flux and kubectl

* Check Git sources fetched by Flux:

```bash theme={null}
flux get sources git
```

Sample output (cropped):

```bash theme={null}
NAME                               REVISION                  SUSPENDED  READY  MESSAGE
2-demo-source-git-bb-app           2-demo@sha1:7dfa8105      False      True   stored artifact for revision '2-demo@sha1:7dfa8105'
3-demo-source-git-bb-app           3-demo@sha1:990e6de9      False      True   stored artifact for revision '3-demo@sha1:990e6de9'
5-demo-source-git-helm-bb-app      5-demo@sha1:d327af27      False      True   stored artifact for revision '5-demo@sha1:d327af27'
flux-system                        main@sha1:44e8ef71        False      True   stored artifact for revision 'main@sha1:44e8ef71'
```

* Check HelmReleases:

```bash theme={null}
flux get helmreleases
```

Sample output:

```bash theme={null}
NAME                                    REVISION  SUSPENDED  READY  MESSAGE
5-demo-helm-release-git-helm-bb-app     7.5.0     False      True   Release reconciliation succeeded
```

* Verify the target namespace and workloads (example using namespace `5-demo`):

```bash theme={null}
kubectl -n 5-demo get all
```

Sample output:

```bash theme={null}
NAME                                           READY  STATUS   RESTARTS  AGE
pod/block-buster-helm-app-569fd8d99-g9xt9     1/1    Running  0         2m6s
pod/block-buster-helm-app-569fd8d99-v85rx     1/1    Running  0         2m6s

NAME                            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
service/block-buster-helm-app   NodePort   10.96.185.58   <none>        80:30005/TCP    2m6s

NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/block-buster-helm-app   2/2     2            2           2m6s
```

Show pod labels (from the override values)

```bash theme={null}
kubectl -n 5-demo get po --show-labels
```

Sample output:

```bash theme={null}
NAME                                           READY  STATUS   RESTARTS  AGE   LABELS
block-buster-helm-app-569fd8d99-g9xt9          1/1    Running  0         2m6s  app=block-buster,env=dev,pod-template-hash=569fd8d99,version=7.5.0
block-buster-helm-app-569fd8d99-v85rx          1/1    Running  0         2m6s  app=block-buster,env=dev,pod-template-hash=569fd8d99,version=7.5.0
```

How the chart artifact is created

* When the `HelmRelease` is reconciled, the source-controller packages the chart from the `GitRepository` and creates a `HelmChart` artifact (CRD `helmcharts.source.toolkit.fluxcd.io`).
* List packaged charts:

```bash theme={null}
flux get sources chart
```

Sample output:

```bash theme={null}
NAME                                                         REVISION   SUSPENDED   READY   MESSAGE
flux-system-5-demo-helm-release-git-helm-bb-app               7.5.0      False       True    packaged 'block-buster-helm-app' chart with version '7.5.0'
```

Inspect the HelmChart CRD in the `flux-system` namespace:

```bash theme={null}
kubectl -n flux-system get helmcharts.source.toolkit.fluxcd.io
```

View the YAML to see artifact details and the storage URL (the artifact URL points to source-controller storage).

What else you can configure in HelmRelease

* Helm tests: enable post-install/upgrade tests.
* Upgrade remediation: retries, remediation strategies like rollback, and whether to ignore test failures.
* CRD policies: `Skip`, `Create`, `CreateReplace` for CRD upgrades.

For the full set of options, see the Flux HelmRelease documentation:

* [https://fluxcd.io/docs/components/helm/helmreleases/](https://fluxcd.io/docs/components/helm/helmreleases/)

Useful resources and CRDs

| Resource Type | Purpose | Example |
| - | - | - |
| `GitRepository` | Source-controller fetches Git repos | `apiVersion: source.toolkit.fluxcd.io/v1beta2` |
| `HelmRelease` | Helm Controller installs/updates a Helm chart | `apiVersion: helm.toolkit.fluxcd.io/v2beta1` |
| `HelmChart` | Packaged chart artifact created by source-controller | `helmcharts.source.toolkit.fluxcd.io` |

Important: Ensure the Git branch and chart path are correct and reachable by Flux. If you use `flux create ... --export`, the CLI reads local files (like `--values`) on your machine — missing files will result in incomplete exports. Also commit the generated HelmRelease to the repo Flux watches so the controllers can reconcile it.

Check the application UI

* In this demo the service is exposed on NodePort `30005`. Open `http://localhost:30005` from any node where the NodePort is reachable.
* From version 7.5.0 the app shows a "START GAME" button to start the game manually (instead of auto-starting).

![A webpage showing a "BLOCK BUSTER" breakout-style game with colored bricks, a paddle and ball, and a "START GAME" button at the bottom. The header panel above the game displays pod/app info (Pod Name, Pod IP, Namespace, App Version) along with the current Level, Score (1600) and Lives.](https://mintcdn.com/kodekloud-c4ac6d9a/AyhVWHpoMIYCWiei/images/GitOps-with-FluxCD/Helm-Controller-and-OCI-Registry/Demo-Helm-Controller-with-Git-as-Source/breakout-blockbuster-pod-info-game.jpg?fit=max\&auto=format\&n=AyhVWHpoMIYCWiei\&q=85\&s=103c4bf64748403f7277a5b4bced5e43)

That covers the core steps to deploy a Helm chart from a Git repository using Flux's source-controller and Helm controller. For extended configuration and advanced HelmRelease options, consult the Flux docs:

Links and references

* Flux Source Controller: [https://fluxcd.io/docs/components/source/](https://fluxcd.io/docs/components/source/)
* Flux Helm Controller: [https://fluxcd.io/docs/components/helm/helm-controller/](https://fluxcd.io/docs/components/helm/helm-controller/)
* Flux HelmRelease docs: [https://fluxcd.io/docs/components/helm/helmreleases/](https://fluxcd.io/docs/components/helm/helmreleases/)

> **[Watch Video](https://learn.kodekloud.com/user/courses/gitops-with-fluxcd/module/205ec7c7-4cb6-4ecb-9bb5-fa50419f1e68/lesson/5a8c0ef3-506e-4d48-a25d-42d22bdc4da4)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.