GitOps for Hosting Deployments: Declarative Infrastructure from Git
If It Is Not in Git, It Did Not Happen
GitOps is a simple idea with profound operational consequences: your Git repository is the single source of truth for everything — application code, infrastructure configuration, deployment manifests, and environment settings. Changes happen by committing to Git, not by running commands against production. An automated agent watches the repository and continuously reconciles the actual state of your infrastructure with the declared state in Git. If someone makes a manual change, the agent reverts it. If a new commit changes a configuration, the agent applies it.
For hosting customers running containerised workloads, GitOps replaces ad-hoc deployment scripts, manual kubectl commands, and SSH-and-prayer workflows with a process that is auditable, reversible, and consistent. This guide covers the principles, the tooling, and the practical implementation of GitOps for hosting deployments.
Core Principles of GitOps
Declarative Configuration
The entire desired state of your system is described declaratively — Kubernetes manifests, Terraform configurations, Helm charts, or Kustomize overlays. Declarative means you specify what the system should look like, not the steps to get there. The GitOps agent handles the how.
Version-Controlled Source of Truth
All declarations live in Git. Every change is a commit with a timestamp, an author, and a message explaining the intent. The history of your infrastructure is the Git log. If you need to know who changed the replica count for the API service last Thursday, git log tells you.
Automated Reconciliation
An agent running inside your cluster continuously compares the desired state (from Git) against the actual state (in the cluster). When they differ, the agent acts — applying new configurations, rolling back drift, and reporting discrepancies. This is the operational heart of GitOps: the system self-heals toward the declared state.
Pull-Based Delivery
Unlike traditional CI/CD where the pipeline pushes changes to the cluster, GitOps uses a pull model. The agent inside the cluster pulls the desired state from Git. This means the CI/CD pipeline never needs direct access to your production cluster — it just pushes commits to the repository. The security implications are significant: your deployment credentials live inside the cluster, not in your CI system.
Tooling: Argo CD and Flux
Two tools dominate the GitOps landscape for Kubernetes deployments:
Argo CD
Argo CD provides a web UI, CLI, and API for managing GitOps applications. It supports Kubernetes manifests, Helm charts, Kustomize, and Jsonnet. The web UI shows the real-time sync status of every application, the diff between the desired and actual state, and the deployment history. Argo CD is well-suited for teams that want visual oversight of their deployments.
Flux
Flux takes a more composable approach, using a set of Kubernetes controllers that each handle a specific concern: source management, Kustomize/Helm rendering, image automation, and notification. Flux is deeply integrated with Kubernetes native patterns and is well-suited for teams that prefer declarative configuration over UI-driven management.
Which to Choose
Both are CNCF graduated projects. Both are production-ready. Choose Argo CD if your team values a rich UI and multi-cluster management from a central dashboard. Choose Flux if your team prefers a more Kubernetes-native, controller-based approach. The principles are identical — the difference is operational preference.
Repository Structure
How you organise your GitOps repository matters for maintainability:
Monorepo vs Multi-Repo
- Monorepo: All manifests for all environments and services in a single repository. Simple to navigate and search. Access control is coarser — everyone with repository access can see everything.
- Multi-repo: Separate repositories per team, per service, or per environment. Better access control granularity. More complex to manage across repositories.
Environment Separation
Use directory structure or branches to separate environments. A common pattern: environments/staging/ and environments/production/ directories, each containing environment-specific overrides (Kustomize overlays or Helm values). Changes flow from staging to production by promoting the configuration — copying or merging the staging values into the production directory after validation.
The GitOps Deployment Workflow
- Developer pushes code: Application code changes go through the standard CI pipeline — build, test, create container image, push to registry.
- CI updates the manifest: The CI pipeline updates the image tag in the GitOps repository (or an automated image updater detects the new tag and creates a commit).
- Pull request for review: The manifest change goes through a pull request. Teammates review the deployment change — what image version, what configuration changes, what environment.
- Merge triggers deployment: When the pull request is merged, the GitOps agent detects the change and applies it to the cluster. The deployment rolls out according to the configured strategy (rolling update, blue-green, canary).
- Agent reports status: The agent reports whether the sync was successful, whether the deployment is healthy, and whether the new pods are ready.
Rollbacks
Rolling back in GitOps is trivially simple: revert the Git commit. The agent detects the reverted state and rolls the cluster back to the previous configuration. No special rollback commands, no SSH access, no manual intervention. The audit trail in Git shows exactly when the rollback happened and who initiated it.
Drift Detection and Self-Healing
One of the most valuable features of GitOps is drift detection. If someone makes a manual change to the cluster — editing a deployment directly, scaling a replica set manually, changing a ConfigMap — the agent detects the drift and either alerts or auto-reverts the change, depending on your configuration.
This prevents the common scenario where production configuration diverges from what the team believes is deployed. In a GitOps workflow, the Git repository is always correct, and the cluster is always reconciled to match it.
Secrets Management
Secrets require special handling in GitOps. You cannot store plaintext secrets in Git. Common approaches:
- Sealed Secrets: Encrypt secrets with a cluster-specific key. The encrypted secret is safe to store in Git. A controller inside the cluster decrypts it.
- SOPS: Mozilla SOPS encrypts secret values within YAML files using cloud KMS or PGP keys. The encrypted file is committed to Git, and the GitOps agent decrypts it during application.
- External Secrets Operator: Synchronises secrets from external secret stores (Vault, cloud provider secret managers) into Kubernetes. The GitOps repository contains a reference to the external secret, not the value itself.
When GitOps Makes Sense
- You run containerised workloads on Kubernetes or a similar orchestrator.
- You want auditable, reversible deployments with clear accountability.
- Multiple team members deploy to shared environments and you need coordination.
- You want to enforce that production matches a declared state — no drift, no surprises.
When It May Be Overkill
- You run a single application on a single VPS. A simple deployment script or CI/CD pipeline is sufficient.
- Your team is one person. The overhead of GitOps tooling may not justify the benefit.
- You do not use containers or Kubernetes. GitOps tooling is heavily Kubernetes-focused.
The Bottom Line
GitOps brings software engineering rigour to infrastructure and deployment management. Git becomes the audit trail, the rollback mechanism, and the collaboration surface. Automated agents ensure the cluster matches the declared state. The result is deployments that are predictable, auditable, and recoverable — which is exactly what hosting customers running production workloads need.