Flux CD Flux CD

Deploy Your First Application with a GitRepository and Kustomization

Point Flux at manifests in Git using a Kustomization resource and watch it sync.

12 min Beginner

Flux is configured with Kubernetes resources like everything else in the cluster. Two of them do most of the work: a source such as a GitRepository says where the configuration lives, and a Kustomization says “take the manifests at this path in that source and keep them applied to this cluster”. This guide deploys a small application, then changes Git to see the sync happen. It assumes Flux is bootstrapped against a fleet-infra repository (see the previous guide).

Prepare the manifests

In your fleet-infra clone, add an application folder alongside the clusters folder created by bootstrap:

fleet-infra/
├── clusters/
│   └── dev/
│       ├── flux-system/        # created by bootstrap
│       └── webapp.yaml         # the Flux Kustomization (next section)
└── apps/
    └── webapp/
        ├── namespace.yaml
        ├── deployment.yaml
        └── service.yaml

apps/webapp/namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: webapp

apps/webapp/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
  namespace: webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
        - name: webapp
          image: nginx:1.25
          ports:
            - containerPort: 80

apps/webapp/service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: webapp
  namespace: webapp
spec:
  selector:
    app: webapp
  ports:
    - port: 80
      targetPort: 80

Unlike some tools, the manifests here name their namespace explicitly, and the folder includes the Namespace object so Flux creates it. No kustomization.yaml is needed: when a folder doesn’t contain one, Flux builds a list of every YAML file in it.

Write the Flux Kustomization

Bootstrap already created a GitRepository named flux-system that points at this same repository, so you can reuse it. clusters/dev/webapp.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: webapp
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/webapp
  prune: true
  wait: true
  timeout: 2m

The parts that matter:

  • sourceRef is where the desired state comes from. Here it is the flux-system repository that bootstrap set up.
  • path is the folder inside the source to apply.
  • interval is how often Flux re-applies the manifests and corrects drift, even when Git hasn’t changed.
  • prune: true means that objects removed from Git are also removed from the cluster. It is off unless you set it.
  • wait and timeout make Flux wait for the applied resources to become ready before reporting success.

You can generate this YAML with the CLI instead of writing it by hand:

flux create kustomization webapp \
  --source=GitRepository/flux-system \
  --path=./apps/webapp \
  --prune=true --wait=true --timeout=2m --interval=10m \
  --export > clusters/dev/webapp.yaml

Commit and let Flux pick it up

git add -A
git commit -m "Add webapp"
git push

The flux-system Kustomization already watches ./clusters/dev, so it discovers the new webapp Kustomization on its next run. You never run kubectl apply for the application. To skip the wait, ask Flux to check Git right now:

flux reconcile source git flux-system
flux get kustomizations --watch

Confirm the deployment

The webapp Kustomization appears and moves to Ready with a message naming the applied revision. Check the cluster, and ask Flux to show what it owns:

kubectl get all -n webapp
flux tree kustomization webapp

Change Git and watch it sync

Edit apps/webapp/deployment.yaml, change the image to nginx:1.26, then commit and push. Flux fetches repositories on the GitRepository interval (one minute by default after bootstrap), then applies the change. A new ReplicaSet rolls out. Verify:

flux reconcile kustomization webapp --with-source
kubectl get deploy webapp -n webapp \
  -o jsonpath='{.spec.template.spec.containers[0].image}'; echo

That is the whole loop: edit Git, Flux converges the cluster. The next guide covers how to control that behavior.

Using a different repository

You don’t have to keep application manifests in the bootstrap repository. To deploy from another one, create a GitRepository for it and reference that from the Kustomization:

flux create source git webapp-config \
  --url=https://github.com/your-org/webapp-config \
  --branch=main --interval=1m \
  --export > clusters/dev/webapp-source.yaml

For a private repository, add credentials with flux create secret git and reference it with --secret-ref, or use an SSH deploy key. Then set sourceRef.name: webapp-config in the Kustomization.

Popular Guides