Flux
If you're self-hosting your homelab on Kubernetes with Flux and want to move off GitHub or GitLab, Codeberg is a solid open-source alternative. Here's how to switch your Flux source repository and the flux-system secret to a new Codeberg endpoint without losing your GitOps workflow.
Onboarding Flux with SSH Keys
Flux authenticates to Git over SSH using a deploy key — a dedicated keypair scoped to a single repository. The private key lives in a Kubernetes secret; the public key is registered on the Git host. This is the foundation that every reconciliation loop depends on.
1. Install the Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash
Verify the install:
flux --version
2. Check cluster prerequisites
flux check --pre
This confirms your cluster version, kubeconfig, and required CRDs are in order before you commit anything.
3. Generate an SSH keypair
ssh-keygen -t ed25519 -C "flux@homelab" -f ./flux_deploy_key -N ""
This produces two files: flux_deploy_key (private, goes into the cluster) and flux_deploy_key.pub (public, goes onto the Git host).
4. Register the public key on Codeberg
Add flux_deploy_key.pub as a deploy key on your repository under Settings → Deploy Keys. Read-only access is sufficient for most setups — only enable write access if Flux needs to push image automation commits.
5. Create the SSH secret in the cluster
flux create secret git flux-system \
--namespace=flux-system \
--url=ssh://git@codeberg.org/johnnycube/homelab.git \
--private-key-file=./flux_deploy_key
The CLI automatically runs ssh-keyscan against Codeberg and bundles the known_hosts entry alongside the private key. You can inspect what was stored:
kubectl -n flux-system get secret flux-system \
-o jsonpath='{.data.known_hosts}' | base64 -d
6. Bootstrap Flux
flux bootstrap git \
--url=ssh://git@codeberg.org/johnnycube/homelab.git \
--branch=main \
--path=clusters/homelab \
--private-key-file=./flux_deploy_key
This installs the Flux controllers into flux-system, commits the manifests to your repo under clusters/homelab, and sets up the initial GitRepository and Kustomization resources. From this point on, any commit to that path triggers a reconciliation automatically.
Verify everything is running:
flux get all -n flux-system
You should see all sources and kustomizations reporting Ready: True.
Migrating Flux GitOps to Codeberg
If you're self-hosting your homelab on Kubernetes with Flux and want to move off GitHub or GitLab, Codeberg is a solid open-source alternative. Here's how to switch your Flux source repository and the flux-system secret to a new Codeberg endpoint without losing your GitOps workflow.
Why Codeberg?
Codeberg is a non-profit, community-driven Git hosting platform built on Gitea. For homelab operators who value self-sovereignty and privacy, it's an appealing alternative to commercial Git hosts. Flux supports any Git server over SSH, so the migration is straightforward.
What You'll Actually Change
Two things need updating:
- The
flux-systemKubernetes secret — this holds your SSH private key and known_hosts entry for the remote Git server. - The
GitRepositoryresource — this tells Flux where to pull manifests from.
Step 1: Generate a Deploy Key
Start by creating a fresh ED25519 keypair:
ssh-keygen -t ed25519 -C "flux@homelab" -f ./flux_deploy_key -N ""
Then add the public key (flux_deploy_key.pub) as a deploy key on your Codeberg repo under Settings → Deploy Keys. Read-only access is sufficient unless Flux needs to push commits or tags.
Step 2: Replace the flux-system Secret
Delete the old secret and recreate it pointing at Codeberg. The flux CLI handles fetching the host key for you:
kubectl -n flux-system delete secret flux-system
flux create secret git flux-system \
--namespace=flux-system \
--url=ssh://git@codeberg.org/johnnycube/homelab.git \
--private-key-file=./flux_deploy_key
This bundles your private key and the codeberg.org known_hosts entry into a single secret. No manual ssh-keyscan step required.
Step 3: Update the GitRepository Source
Patch the existing GitRepository resource with the new URL:
kubectl -n flux-system patch gitrepository flux-system \
--type=merge \
-p '{"spec":{"url":"ssh://git@codeberg.org/johnnycube/homelab.git"}}'
Or re-declare it cleanly with the Flux CLI:
flux create source git flux-system \
--namespace=flux-system \
--url=ssh://git@codeberg.org/johnnycube/homelab.git \
--branch=main \
--secret-ref=flux-system \
--export | kubectl apply -f -
Step 4: Verify
Force a reconciliation and check the status:
flux reconcile source git flux-system -n flux-system
flux get source git -n flux-system
You're looking for Ready: True. If you hit an SSH handshake error, inspect the known_hosts value in the secret:
kubectl -n flux-system get secret flux-system \
-o jsonpath='{.data.known_hosts}' | base64 -d
There should be a line starting with codeberg.org. If it's missing, re-run the flux create secret step — it likely failed silently during host key fetch.
Summary
| What changed | Command |
|---|---|
| SSH secret | flux create secret git flux-system --url=... |
| GitRepository URL | kubectl patch gitrepository or flux create source git |
| Verification | flux reconcile source git + flux get source git |
The whole migration takes under five minutes. Once Flux is reconciling cleanly from Codeberg, you can safely rotate or delete the old deploy key on your previous Git host.