Skip to main content

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:

  1. The flux-system Kubernetes secret — this holds your SSH private key and known_hosts entry for the remote Git server.
  2. The GitRepository resource — 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 changedCommand
SSH secretflux create secret git flux-system --url=...
GitRepository URLkubectl patch gitrepository or flux create source git
Verificationflux 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.