Skip to content

Tutorial: GitOps Setup

This tutorial walks you through initializing LoKO GitOps, pushing your first manifest, and watching the cluster reconcile automatically.

Time required: ~20 minutes

What you’ll learn:

  • Bootstrap GitOps on a LoKO cluster
  • Explore the scaffolded GitOps repository
  • Deploy a Kubernetes resource by pushing a git commit
  • Observe provider reconciliation in real time
  • Tear down the GitOps setup cleanly

Before starting, ensure you have:

  • A running LoKO environment (loko env create completed)
  • Forgejo deployed and accessible at http://forgejo.<your-domain>
  • One of flux-operator or argocd in your workloads
  • loko catalog sync run at least once

If you don’t have Forgejo yet:

Terminal window
loko workloads add forgejo
loko workloads add flux-operator
loko env deploy # deploy new workloads to the running cluster
loko catalog sync

Bootstrap GitOps with FluxCD (recommended):

Terminal window
loko gitops init --provider fluxcd

Or with ArgoCD if you prefer a web UI:

Terminal window
loko gitops init --provider argocd

You’ll see LoKO working through each bootstrap step:

✓ Forgejo auth validated
✓ Created repository gitops
✓ Installed flux-operator (FluxCD v2.3.0)
✓ Scaffolded repository (11 templates rendered)
✓ Applied bootstrap resources (GitRepository + Kustomization)
✓ Created cluster secrets (forgejo-gitops-auth, webhook-token)
✓ Registered push webhook on Forgejo
✓ Waiting for first sync... done
✓ Updated loko.yaml (gitops.enabled: true)
GitOps is ready. Push commits to gitops to reconcile the cluster.

Open the Forgejo web UI at http://forgejo.<your-domain> and find the gitops repository. Copy the clone URL and clone it locally:

Terminal window
git clone http://forgejo.<your-domain>/<your-user>/gitops.git
cd gitops

List the contents of the scaffolded repository:

gitops/
├── clusters/dev/
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ ├── http-webhook.yaml
│ └── receiver.yaml ← (FluxCD only)
├── .flux/
│ ├── git-repo.yaml
│ └── flux-kustomization.yaml
├── .gitea/workflows/
│ └── hello.yaml
├── .gitignore
└── README.md

Open clusters/dev/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- http-webhook.yaml
- receiver.yaml

This is the Kustomize entry point. Everything listed under resources is reconciled into the cluster automatically.

The scaffold includes a simple HTTP echo app. Open your browser and visit:

https://echo.<your-apps-domain>

You should see a JSON response with request headers echoed back. This confirms GitOps is working end-to-end.

LoKO also creates a sample-webapp repository for CI + preview demos. PR previews are:

  • FluxCD: label-driven (preview / preview-built)
  • ArgoCD: title-driven ([preview-built])

Step 4b: Explore sample-webapp and PR generation

Section titled “Step 4b: Explore sample-webapp and PR generation”

Open the sample-webapp repo in Forgejo and check .gitea/workflows/:

  • sample-webapp-build.yaml — builds/pushes main-*, updates dev image tag in gitops
  • sample-webapp-pr.yaml — builds pr-<N>-<sha7> preview images
  • sample-webapp-promote.yaml — promotes dev tag to prod in gitops

PR preview generation is provider-specific:

ProviderTriggerGenerated resources
FluxCDPR labels preview / preview-builtNamespace + GitRepository + Kustomization
ArgoCDPR title contains [preview-built]ApplicationSet generates per-PR Application

In both cases, a PR image is pushed to the container registry only when preview is requested via the preview label. Deployment happens only after the pushed artifact is marked deployable: preview-built label for FluxCD, and [preview-built] in the PR title for ArgoCD. If the PR is already open when you decide it is ready, add the preview label and comment /preview to trigger the preview build immediately.

Preview host format for both:

https://sample-webapp-pr-<N>.<apps-domain>
Terminal window
loko gitops status

Expected output:

FluxCD v2.3.0 Ready
Name Namespace Status Last Sync Message
clusters-dev flux-system Applied 1 minute ago

All green means the provider is healthy and the initial commit has been reconciled successfully.

Create a simple ConfigMap under clusters/dev/:

Terminal window
cat > clusters/dev/app-config.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: loko-apps
data:
LOG_LEVEL: debug
APP_ENV: development
EOF

Register it in kustomization.yaml by adding the file to the resources list:

resources:
- namespace.yaml
- http-webhook.yaml
- receiver.yaml
- app-config.yaml # ← add this line

Commit and push:

Terminal window
git add clusters/dev/app-config.yaml clusters/dev/kustomization.yaml
git commit -m "feat: add app-config configmap"
git push

The Forgejo push webhook immediately notifies the provider. Within seconds you should see the ConfigMap appear:

Terminal window
kubectl get configmap app-config -n loko-apps

Check the sync status:

Terminal window
loko gitops status
FluxCD v2.3.0 Ready
Name Namespace Status Last Sync Message
clusters-dev flux-system Applied 5 seconds ago

For FluxCD, you can also tail the controller logs directly:

Terminal window
kubectl logs -n flux-system deploy/kustomize-controller -f

Step 8: Inspect the webhook delivery in Forgejo

Section titled “Step 8: Inspect the webhook delivery in Forgejo”

Open the Forgejo web UI and navigate to your gitops repository:

  1. Go to Settings → Webhooks
  2. Click the webhook entry
  3. Scroll to Recent Deliveries

You should see a successful delivery (HTTP 200) triggered by your push. This confirms the webhook chain is working.

Step 9: (Optional) Open the provider dashboard

Section titled “Step 9: (Optional) Open the provider dashboard”

FluxCD: Open https://flux.<your-domain> — the Flux Operator Mission Control dashboard is enabled by default in LoKO.

ArgoCD: Open https://argocd.<your-domain>. Log in with:

Terminal window
loko workloads connect argocd --show-password

You’ll see your GitOps application listed with its sync state, resource tree, and health indicators.

When you’re done, tear down the GitOps setup:

Terminal window
loko gitops destroy

LoKO will show you exactly what it’s about to do:

The following actions will be performed:
• Delete fluxcd CRs from cluster
• Uninstall fluxcd Helm releases
• Delete fluxcd CRDs from cluster
• Delete fluxcd namespace
• Remove Forgejo webhook from repo 'gitops'
• Delete Forgejo repo 'gitops'
• Revoke access token 'loko-gitops-dev'
• Set gitops.enabled: false in loko.yaml
Proceed with destroy? [y/N]

Confirm and the full teardown completes in about 30 seconds.

  • loko gitops init bootstraps Forgejo + FluxCD/ArgoCD in one command
  • The scaffolded repo under clusters/<env>/ is continuously reconciled by the provider
  • A git push triggers immediate cluster reconciliation via the Forgejo webhook
  • loko gitops status shows provider health and per-workload sync state
  • loko gitops destroy cleanly removes all GitOps resources and secrets