GitOps with GitLab
Learn how GitLab integrates Flux for GitOps. From OCI artifact sources and immediate reconciliation to drift remediation and migration from legacy GitOps, build pull-based deployments that keep your cluster in sync.
GitOps flips the deployment model. Instead of a pipeline pushing changes to a cluster, an operator inside the cluster pulls the desired state from a source and reconciles the cluster to match. The source — typically a Git repository or an OCI artifact — is the single source of truth. If someone manually changes the cluster, the operator detects the drift and reverts it. If a deployment fails, reverting the source reverts the cluster. This is the pull-based model, and GitLab recommends it for production deployments because it has a stronger security model than CI/CD push deployments [citation:2][citation:4].
GitLab integrates Flux as its GitOps operator. Flux runs inside the cluster, watches the source, and applies changes. The GitLab agent (agentk) complements Flux: it simplifies the Flux setup, provides cluster-to-GitLab access management, and visualizes the cluster state in the GitLab UI. Together, Flux keeps the cluster synchronized while the agent provides visibility and control [citation:1][citation:2].
The recommended source for Flux is not a Git repository but an OCI artifact stored in the GitLab Container Registry. OCI artifacts are immutable, designed for scale, and can be security-scanned. A Git repository is mutable and its default branch triggers a sync when used to store cluster state — a problem if you push documentation changes. OCI artifacts separate the source of truth (Git) from the delivery mechanism (OCI), giving you the best of both [citation:1][citation:2].
Flux
flux bootstrap.GitLab Agent
OCI Artifact
Immediate Reconciliation
Drift Remediation
Migration
gitops.manifest_projects) is deprecated. Migrate to Flux by removing the config and running flux bootstrap.The deployment sequence starts with a developer pushing code to an application repository. That push triggers a GitLab CI/CD pipeline, which builds a container image and pushes it to the registry. A separate delivery repository — or a job within the same pipeline — builds an OCI artifact containing the Kubernetes manifests (with the new image tag) and pushes it to the container registry. The agent detects the push and notifies Flux, which pulls the OCI artifact and applies the changes to the cluster [citation:1][citation:4].
This separation is intentional. The application repository is for code. The delivery repository (or the OCI artifact) is for the desired state of the cluster. A single Git repository can be the source for multiple OCI artifacts, each packaging a small set of manifests. This avoids downloading an entire repository just to retrieve a few manifests, and it lets Flux follow a well-known versioning scheme — semantic versions, for example — so it can auto-deploy patch releases while requiring manual approval for major versions [citation:2][citation:6].
The agent's role is to make Flux easier to use with GitLab. Without the agent, you would configure Flux manually with deploy tokens and GitRepository objects. With the agent, Flux is bootstrapped with a single command, and the agent configures the Receiver webhook automatically. The agent also shows the cluster state in the GitLab UI, so you can see what's deployed without leaving GitLab [citation:1][citation:2].
- No cluster API exposure: Flux runs in the cluster; GitLab never connects to the API
- Drift remediation: Manual changes are reverted automatically
- Audit trail: Every change is a commit or artifact in GitLab
- Rollback: Revert a commit or deploy a previous artifact
- Scale: OCI artifacts are designed for high-volume pulls
Using OCI artifacts instead of Git repositories as the Flux source is a deliberate architectural choice. Git repositories are mutable: a force-push rewrites history, and the default branch triggers a sync whenever it changes. If you store cluster state in the default branch, every documentation change triggers a reconciliation. OCI artifacts are immutable: a pushed artifact cannot be changed, and its version (tag) identifies exactly what it contains [citation:1][citation:2].
The GitLab Container Registry supports OCI artifacts natively. You build the artifact with flux push artifact, using the registry credentials that GitLab provides to every job. The artifact contains the Kubernetes manifests (or Kustomize overlays, or Helm charts) that define the desired state. Flux's OCIRepository resource points to the artifact, and a Kustomization resource applies it to the cluster [citation:2][citation:4].
The OCI artifact is a cache layer between Git and the cluster. The real source of truth remains the Git repository — the artifact is built from it. This means you get the reviewability of Git (merge requests, approvals, history) and the immutability and scalability of OCI. It also means the artifact can be security-scanned by the container registry, catching vulnerabilities before they reach the cluster [citation:6].
- OCI: Immutable, scannable, scalable, separate from source code
- Git: Mutable, default branch triggers sync, not designed for high-volume pulls
- Recommendation: Use OCI for cluster state; keep Git for source code and review