> ## 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 Source Controller Git Manifest in Flux Repo

> Demonstrates how Flux source controller fetches Git manifests and how Kustomize controller applies them, including generated CRs, artifact storage, and deploying an example app.

In this lesson we walk through how the Flux source controller fetches manifests from a Git repository and how the Kustomize controller is wired to apply those manifests. We'll show the generated sync manifest (GitRepository + Kustomization), how to prepare an example app repo, and how Flux stores and applies the fetched artifacts.

We already cloned the block-buster repository locally and applied the generated gotk-sync manifest to the cluster. The gotk-sync manifest contains two key CRs: a GitRepository (the source) and a Kustomization (the consumer).

![A screenshot of Visual Studio Code connected to WSL (Ubuntu 18.04) showing the file explorer with several config/YAML files on the left and an integrated terminal at the bottom displaying a root prompt. The main editor area shows the VS Code welcome background and command hints.](https://mintcdn.com/kodekloud-c4ac6d9a/AyhVWHpoMIYCWiei/images/GitOps-with-FluxCD/Source-and-Kustomize-Controller/Demo-Source-Controller-Git-Manifest-in-Flux-Repo/vscode-wsl-ubuntu1804-file-explorer-terminal.jpg?fit=max\&auto=format\&n=AyhVWHpoMIYCWiei\&q=85\&s=b551700602ee1ba58cfa8f340de640fc)

Example generated manifest (GitRepository + Kustomization):

```yaml theme={null}
# This manifest was generated by flux. DO NOT EDIT.
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 10s
  ref:
    branch: main
  secretRef:
    name: flux-system
  url: ssh://git@github.com/sidd-harth-2/block-buster
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 10s
  path: ./flux-clusters/dev-cluster
  prune: true
  sourceRef:
    kind: GitRepository
    name: flux-system
```

What each CR does

* GitRepository (apiVersion: `source.toolkit.fluxcd.io/v1beta2`) configures where the source controller fetches manifests from:
  * `url` — HTTP or SSH Git URL.
  * `ref.branch` — branch to track (example: `main`).
  * `secretRef` — Kubernetes Secret used for authentication (required for private SSH repos).
  * `interval` — how often the source controller checks the repo for changes.
* Kustomization (apiVersion: `kustomize.toolkit.fluxcd.io/v1beta2`) tells the Kustomize controller which artifacts to apply:
  * `sourceRef` points to the GitRepository defined above.
  * `path` selects the subdirectory in the repo to apply.
  * `prune: true` enables deletion of resources removed from the Git path.

Key fields at a glance:

| Resource | Important fields | Purpose / notes |
| -: | - | - |
| GitRepository | `spec.url`, `spec.ref.branch`, `spec.secretRef`, `spec.interval` | Where to fetch manifests; use `secretRef` for private SSH repos. |
| Kustomization | `spec.sourceRef`, `spec.path`, `spec.interval`, `spec.prune` | Points to the source artifact and path to apply; `prune` removes resources not present in Git. |

If you use an SSH Git URL, ensure a matching Secret exists in the same namespace (for example `flux-system`) containing the private key. For public HTTPS repos, authentication is not required.

Inspecting Flux sources and kustomizations with the Flux CLI:

```bash theme={null}
# List supported source kinds:
flux get sources
# List Git sources:
flux get sources git

# Example output:
# NAME         REVISION                 SUSPENDED  READY  MESSAGE
# List kustomizations:
flux get kustomizations

# Example output:
# NAME         REVISION                 SUSPENDED  READY  MESSAGE
# flux-system  main@sha1:edf2288f       False      True   Applied revision: main@sha1:edf2288f
```

Example repository used in this lesson: `sid-demo/bb-app-source`. It contains application source code in `src/` and Kubernetes manifests in `manifests/`. For the demo we imported this repository into our own GitHub account and used branch `1-demo`.

![A dark-mode GitHub repository page showing the "sid-demo / bb-app-source" repo's src folder with files Dockerfile and index.php. The header shows the main branch, commit history, and buttons like "Go to file" and "Add file."](https://mintcdn.com/kodekloud-c4ac6d9a/AyhVWHpoMIYCWiei/images/GitOps-with-FluxCD/Source-and-Kustomize-Controller/Demo-Source-Controller-Git-Manifest-in-Flux-Repo/github-dark-bb-app-src-dockerfile.jpg?fit=max\&auto=format\&n=AyhVWHpoMIYCWiei\&q=85\&s=94dd5b4b1956b0cf4b26be0cc1d93509)

I imported the repository into my GitHub account using the Import repository feature.

![A screenshot of GitHub's "Import your project to GitHub" page showing fields for the old repository clone URL and new repository details (owner and repository name "bb-app-source"), with visibility options and a "Begin import" button. The interface is in dark mode.](https://mintcdn.com/kodekloud-c4ac6d9a/AyhVWHpoMIYCWiei/images/GitOps-with-FluxCD/Source-and-Kustomize-Controller/Demo-Source-Controller-Git-Manifest-in-Flux-Repo/github-import-bb-app-source-dark.jpg?fit=max\&auto=format\&n=AyhVWHpoMIYCWiei\&q=85\&s=d3f94f3589c8c1a7e755ee66b2ddd251)

After import I cloned the repo locally and checked out the `1-demo` branch.

![A dark‑mode GitHub repository page for "sidd-harth-2 / bb-app-source" showing the Code tab and the main branch. It lists folders like "manifests" and "src," shows a notice that the main branch isn't protected, and prompts to add a README.](https://mintcdn.com/kodekloud-c4ac6d9a/AyhVWHpoMIYCWiei/images/GitOps-with-FluxCD/Source-and-Kustomize-Controller/Demo-Source-Controller-Git-Manifest-in-Flux-Repo/github-dark-repo-main-branch-code.jpg?fit=max\&auto=format\&n=AyhVWHpoMIYCWiei\&q=85\&s=d17e3f30f90ce89dbb744a2a02e0acea)

Local clone and branch checkout:

```bash theme={null}
git clone https://github.com/sidd-harth-2/bb-app-source
cd bb-app-source
git checkout 1-demo
```

Repository structure (high-level)

| Path | Purpose |
| - | - |
| `src/` | PHP frontend that prints pod metadata (reads environment variables injected into pods). |
| `manifests/` | Kubernetes manifests for the app: `deployment.yml`, `namespace.yml`, `service.yml`. |
| Prebuilt images | Multiple versioned images (example: `7.1.0`). |

Example HTML/PHP snippet (the app reads pod metadata from environment variables):

```html theme={null}
<td style='background-color:#222222'><h3>&nbsp;&nbsp; " . getenv("MY_POD_NAME") . "</h3></td>
</tr>
<tr>
<td style='background-color:#3C3C3C'><h2>&nbsp;&nbsp; Pod IP</h2></td>
<td style='background-color:#3C3C3C'><h3>&nbsp;&nbsp; " . getenv("MY_POD_IP") . "</h3></td>
</tr>
<tr>
<td style='background-color:#222222'><h2>&nbsp;&nbsp; Namespace</h2></td>
<td style='background-color:#222222'><h3>&nbsp;&nbsp; " . getenv("MY_POD_NAMESPACE") . "</h3></td>
</tr>
```

Deployment (excerpt showing labels and image):

```yaml theme={null}
# deployment.yml (excerpt)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: block-buster
  namespace: 1-demo
spec:
  selector:
    matchLabels:
      app: block-buster
  template:
    metadata:
      labels:
        app: block-buster
        api: downward
        usage: global
        env: dev
        version: 7.1.0
    spec:
      containers:
        - name: app
          image: siddharth67/block-buster-dev:7.1.0
          imagePullPolicy: Always
          resources:
            requests:
              memory: "10Mi"
              cpu: "10m"
```

Service manifest (exposes the app on NodePort 30001):

```yaml theme={null}
# service.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: block-buster
  name: block-buster-service
  namespace: 1-demo
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
      nodePort: 30001
  selector:
    app: block-buster
    version: 7.1.0
    env: dev
  type: NodePort
```

To deploy these manifests with Flux, copy the three files into the path Flux is configured to watch (the `path` used in the Kustomization CR above). Example workflow:

```bash theme={null}
# From the cloned app repo
cd manifests

# Copy manifests into the local clone of your flux repo
cp deployment.yml namespace.yml service.yml ../../block-buster/flux-clusters/dev-cluster/1-demo/

# Commit & push in the flux-clusters repo:
cd ../../block-buster/flux-clusters
git add .
git commit -m "one-demo"
git push origin main
```

After pushing, the Flux source controller will detect the new commit and store an artifact (tarball). The Kustomize controller then applies the resources referenced by the Kustomization.

Verify status and artifacts:

```bash theme={null}
# Check namespaces before the deploy
kubectl get ns

# Check Flux Git sources and kustomizations:
flux get sources git
# Example output:
# NAME         REVISION             SUSPENDED READY MESSAGE
flux get kustomizations
# Example output:
# NAME         REVISION             SUSPENDED READY MESSAGE
# flux-system  main@sha1:cf1664a0   False     True   Applied revision: main@sha1:cf1664a0
```

Inspecting what the source controller fetched
The source controller stores a tarball of the fetched repo content under `/data/gitrepository/<name>/<name>/`. You can exec into the `source-controller` pod to list and inspect the tarball:

```bash theme={null}
# List the fetch artifacts
kubectl -n flux-system exec -it deploy/source-controller -- sh -c "ls -l /data/gitrepository/flux-system/flux-system"
# Example output (abbreviated):
# total 36
# lrwxrwxrwx 1 nobody 1337 91 Apr  5 19:59 latest.tar.gz -> /data/gitrepository/flux-system/flux-system/cf1664a0b900bca04af6f3b2cdf210ffe772e8b9.tar.gz
# Show tarball contents without extracting:
kubectl -n flux-system exec -it deploy/source-controller -- sh -c "tar -tf /data/gitrepository/flux-system/flux-system/latest.tar.gz"
# Example output includes:
# flux-clusters/
# flux-clusters/dev-cluster/
# flux-clusters/dev-cluster/1-demo/deployment.yml
# flux-clusters/dev-cluster/1-demo/namespace.yml
# flux-clusters/dev-cluster/1-demo/service.yml
# flux-clusters/dev-cluster/flux-system/gotk-components.yaml
# flux-clusters/dev-cluster/flux-system/gotk-sync.yaml
# flux-clusters/dev-cluster/flux-system/kustomization.yaml
```

Once the Kustomize controller applies the manifests, the namespace and resources appear in the cluster:

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

# Example output:
# NAME                                  READY   STATUS    RESTARTS   AGE
# pod/block-buster-6dbc75ddbc-ppq7r     1/1     Running   0          3m25s
#
# NAME                                  TYPE      CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
# service/block-buster-service          NodePort  10.110.102.187   <none>        80:30001/TCP    3m25s
#
# NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
# deployment.apps/block-buster          1/1     1            1           3m25s
#
# NAME                                          DESIRED   CURRENT   READY   AGE
# replicaset.apps/block-buster-6dbc75ddbc        1         1         1       3m25s
```

Accessing the app
You can reach the app via the NodePort, for example:

* `http://<node-ip>:30001`
* `http://localhost:30001` (if your node is local)

The application is a simple Block Buster game that shows pod metadata (name, IP, namespace, node, version) in the UI.

![A screenshot of a web-based "BLOCK BUSTER" arcade game showing game info (pod name, IP, namespace, etc.) at the top and a black play area with colorful brick rows, a paddle at the bottom, and a blue ball in play.](https://mintcdn.com/kodekloud-c4ac6d9a/AyhVWHpoMIYCWiei/images/GitOps-with-FluxCD/Source-and-Kustomize-Controller/Demo-Source-Controller-Git-Manifest-in-Flux-Repo/block-buster-arcade-pod-info-bricks.jpg?fit=max\&auto=format\&n=AyhVWHpoMIYCWiei\&q=85\&s=63b9d28b9bbf24699a70557809d81347)

Summary and key takeaways

* The Flux source controller polls the configured `GitRepository` and stores an artifact (tarball) of the repository state for the specified revision.
* The `Kustomization` resource points to that source and a `path` within the repo. The Kustomize controller applies resources found in that path.
* `spec.interval` controls polling frequency; `spec.prune: true` will delete cluster resources that are removed from Git when the Kustomization is reconciled.
* For private SSH repos ensure a Secret with the SSH private key exists in the same namespace as the GitRepository.

Further reading and references

* Flux GitRepository and source controller: [https://fluxcd.io/docs/components/source/](https://fluxcd.io/docs/components/source/)
* Kustomization and kustomize-controller: [https://fluxcd.io/docs/components/kustomize/](https://fluxcd.io/docs/components/kustomize/)
* Flux CLI documentation: [https://fluxcd.io/docs/cmd/](https://fluxcd.io/docs/cmd/)
* GitHub Import repository feature: [https://docs.github.com/en/importing-your-projects-to-github/importing-a-repository-with-github-importer](https://docs.github.com/en/importing-your-projects-to-github/importing-a-repository-with-github-importer)

We will next deep-dive into the Kustomize controller and how it applies and manages these manifests.

> **[Watch Video](https://learn.kodekloud.com/user/courses/gitops-with-fluxcd/module/857e34cf-a086-433b-bf3b-88a5a5096a6f/lesson/d33d485b-ce5e-4b8b-afa2-790d05c9bbd6)**

> **[Practice Lab](https://learn.kodekloud.com/user/courses/gitops-with-fluxcd/module/857e34cf-a086-433b-bf3b-88a5a5096a6f/lesson/12f2f5ac-6a4d-4ad9-ae7f-38ae5ca23e3b)**


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