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
Prerequisites
Section titled “Prerequisites”Before starting, ensure you have:
- A running LoKO environment (
loko env createcompleted) - Forgejo deployed and accessible at
http://forgejo.<your-domain> - One of
flux-operatororargocdin your workloads loko catalog syncrun at least once
If you don’t have Forgejo yet:
loko workloads add forgejoloko workloads add flux-operatorloko env deploy # deploy new workloads to the running clusterloko catalog syncStep 1: Run loko gitops init
Section titled “Step 1: Run loko gitops init”Bootstrap GitOps with FluxCD (recommended):
loko gitops init --provider fluxcdOr with ArgoCD if you prefer a web UI:
loko gitops init --provider argocdYou’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.Step 2: Clone the scaffolded repository
Section titled “Step 2: Clone the scaffolded repository”Open the Forgejo web UI at http://forgejo.<your-domain> and find the gitops repository. Copy the clone URL and clone it locally:
git clone http://forgejo.<your-domain>/<your-user>/gitops.gitcd gitopsStep 3: Explore the structure
Section titled “Step 3: Explore the structure”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.mdOpen clusters/dev/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - namespace.yaml - http-webhook.yaml - receiver.yamlThis is the Kustomize entry point. Everything listed under resources is reconciled into the cluster automatically.
Step 4: Confirm the seed app is running
Section titled “Step 4: Confirm the seed app is running”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/pushesmain-*, updates dev image tag ingitopssample-webapp-pr.yaml— buildspr-<N>-<sha7>preview imagessample-webapp-promote.yaml— promotes dev tag to prod ingitops
PR preview generation is provider-specific:
| Provider | Trigger | Generated resources |
|---|---|---|
| FluxCD | PR labels preview / preview-built | Namespace + GitRepository + Kustomization |
| ArgoCD | PR 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>Step 5: Check the GitOps status
Section titled “Step 5: Check the GitOps status”loko gitops statusExpected output:
FluxCD v2.3.0 Ready
Name Namespace Status Last Sync Messageclusters-dev flux-system Applied 1 minute agoAll green means the provider is healthy and the initial commit has been reconciled successfully.
Step 6: Add a manifest and push
Section titled “Step 6: Add a manifest and push”Create a simple ConfigMap under clusters/dev/:
cat > clusters/dev/app-config.yaml <<EOFapiVersion: v1kind: ConfigMapmetadata: name: app-config namespace: loko-appsdata: LOG_LEVEL: debug APP_ENV: developmentEOFRegister 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 lineCommit and push:
git add clusters/dev/app-config.yaml clusters/dev/kustomization.yamlgit commit -m "feat: add app-config configmap"git pushStep 7: Watch reconciliation
Section titled “Step 7: Watch reconciliation”The Forgejo push webhook immediately notifies the provider. Within seconds you should see the ConfigMap appear:
kubectl get configmap app-config -n loko-appsCheck the sync status:
loko gitops statusFluxCD v2.3.0 Ready
Name Namespace Status Last Sync Messageclusters-dev flux-system Applied 5 seconds agoFor FluxCD, you can also tail the controller logs directly:
kubectl logs -n flux-system deploy/kustomize-controller -fStep 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:
- Go to Settings → Webhooks
- Click the webhook entry
- 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:
loko workloads connect argocd --show-passwordYou’ll see your GitOps application listed with its sync state, resource tree, and health indicators.
Step 10: Clean up
Section titled “Step 10: Clean up”When you’re done, tear down the GitOps setup:
loko gitops destroyLoKO 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.
What You’ve Learned
Section titled “What You’ve Learned”loko gitops initbootstraps 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 statusshows provider health and per-workload sync stateloko gitops destroycleanly removes all GitOps resources and secrets
Next Steps
Section titled “Next Steps”- GitOps User Guide — full reference including secrets handling, advanced flags, and troubleshooting
- Workload Management — add more services to your cluster
- GitOps Workloads — Forgejo, FluxCD, and ArgoCD catalog entries