Flux GitRepository sources are surprisingly flexible, allowing you to point them at any Git provider, not just the mainstream ones like GitHub or GitLab.

Let’s see this in action. Imagine you have a private Gitea instance at git.mycompany.com. Here’s how you’d configure a GitRepository source to pull from it:

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: my-company-repo
  namespace: flux-system
spec:
  interval: 1h
  url: ssh://git@git.mycompany.com/my-org/my-project.git
  ref:
    branch: main
  secretRef:
    name: git-credentials

The key here is the url. Flux uses standard Git URL formats, so ssh://git@git.mycompany.com/my-org/my-project.git is perfectly valid. The secretRef points to a Kubernetes Secret containing your SSH private key for authentication.

apiVersion: v1
kind: Secret
metadata:
  name: git-credentials
  namespace: flux-system
type: kubernetes.io/ssh-auth
stringData:
  ssh-privatekey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5...
    -----END OPENSSH PRIVATE KEY-----

This GitRepository object tells Flux to periodically fetch changes from the main branch of your Gitea repository. If it detects any new commits, it’ll update its internal Git clone and make those changes available to other Flux controllers (like Kustomization or HelmRelease) that depend on this source.

The problem this solves is centralizing your GitOps configuration. Instead of managing individual Git clones on each cluster or relying on ad-hoc deployment scripts, you declare your desired state in Git and let Flux synchronize it. This extends seamlessly to any Git provider that supports standard SSH or HTTPS access, including self-hosted GitLab, Bitbucket Server, or even a simple bare Git repository.

Internally, Flux uses a Git client to perform the clone and fetch operations. When you specify an interval like 1h, Flux will execute git fetch on its managed repository at that frequency. If new commits are found on the configured ref (e.g., branch: main or tag: v1.0.0), Flux updates its local copy. This updated Git commit is then exposed as a Git commit SHA that other Flux resources can reference, ensuring atomic and verifiable deployments.

The ref field is crucial for pinning to specific versions. While branch: main is common for continuous deployment, you can also use tag: v1.2.3 for immutable releases or even commit: <sha> for absolute precision. Flux will ensure its local repository reflects the exact state of that reference.

When using HTTPS for authentication, you’d use a type: kubernetes.io/basic-auth secret and a url like https://git.mycompany.com/my-org/my-project.git. The secret would contain username and password fields.

The interval isn’t just about how often Flux checks for changes; it’s also the upper bound on how stale your deployed configuration can become before Flux notices an update. A shorter interval means faster propagation of changes but increased load on both the Git server and the Flux controller.

Flux’s GitRepository controller doesn’t just clone and fetch; it also manages the lifecycle of the Git checkout. If the repository is unavailable for an extended period (exceeding multiple intervals), Flux will attempt to re-initialize the clone. This resilience is key for maintaining GitOps even through transient network issues.

You can also specify a content directory if you only want to sync a subdirectory of your Git repository. This is useful for monorepos where different applications or configurations reside in separate folders. For example, spec.content: my-app/config would only make the contents of that subdirectory available to downstream resources.

The GitRepository controller is fundamental to Flux, acting as the single source of truth for your cluster’s desired state. Its ability to connect to any Git provider, coupled with robust authentication and version pinning, makes it a versatile and powerful tool for any GitOps workflow.

Once your GitRepository is successfully reconciling, the next logical step is to consume its content with a Kustomization or HelmRelease resource.

Want structured learning?

Take the full Flux course →