What Is GitOps? How Git-Driven Deployments Work (With and Without Kubernetes)

Devops & Infrastructure, Tips & Tricks, and What Is

What Is GitOps? How Git-Driven Deployments Work (With and Without Kubernetes)

GitOps is an approach to infrastructure and deployment management where Git is the single source of truth for everything — application code, infrastructure configuration, deployment settings, and environment definitions. Every change to the system starts as a Git commit. If it's not in Git, it doesn't exist.

The term was coined by Weaveworks in 2017, originally in the context of Kubernetes. But the core idea — use Git workflows to manage infrastructure the same way you manage code — applies far beyond Kubernetes clusters. Any team that deploys from Git is already practicing a form of GitOps, whether they use that label or not.

How GitOps Works

The fundamental loop is simple:

flowchart LR
    A[Developer commits change] --> B[Git repository updated]
    B --> C[Automation detects change]
    C --> D[System applies change]
    D --> E[Actual state matches desired state]
    E --> F[Monitoring confirms]

1. A developer makes a change — could be application code, a server configuration file, an environment variable, a deployment setting — and commits it to Git.

2. An automated process detects the new commit. This could be a CI/CD pipeline triggered by a webhook, or a GitOps operator polling the repository.

3. The automation applies the change to the target system — deploying new code to a server, updating infrastructure, changing configuration.

4. The system continuously ensures that the actual state matches what's defined in Git. If something drifts (a manual change, a failed deployment), the automation detects the discrepancy and corrects it.

That last step — continuous reconciliation — is what separates GitOps from regular CI/CD. In a standard CI/CD pipeline, deployment happens once when triggered. In GitOps, the system actively maintains the desired state over time.

The Four Principles

GitOps is built on four principles, formalized by the OpenGitOps project (a CNCF sandbox project):

1. Declarative — The entire system (infrastructure and applications) is described declaratively. You define what the system should look like, not how to get there. Instead of a script that runs apt install nginx && systemctl start nginx, you declare nginx should be running on port 80 and let the tooling figure out the steps.

2. Versioned and immutable — The desired state is stored in Git, which provides a complete version history. Every change has an author, a timestamp, a commit message, and a diff. Rolling back means reverting a commit, not running a manual undo script.

3. Pulled automatically — Agents inside the system pull the desired state from Git and apply it. This is the pull-based model that distinguishes GitOps from traditional push-based CI/CD.

4. Continuously reconciled — The system continuously compares actual state to desired state and corrects any drift. If someone manually changes a server configuration, the GitOps operator detects the difference and reverts it to match Git.

Push-Based vs. Pull-Based: The Key Distinction

This is the most important concept in GitOps, and the source of most confusion:

flowchart TD
    subgraph Push["Push-Based (Traditional CI/CD)"]
        A1[Git Commit] --> A2[CI Pipeline]
        A2 --> A3[Pipeline pushes to servers]
    end

    subgraph Pull["Pull-Based (GitOps)"]
        B1[Git Commit] --> B2[Git Repository]
        B3[Agent in cluster polls Git] --> B2
        B3 --> B4[Agent applies changes]
    end

Push-based — A CI/CD pipeline detects a code change and pushes it to the target environment. The pipeline has credentials to access your servers. This is how most deployment tools work, including DeployHQ, Jenkins, and GitHub Actions.

Pull-based — An agent running inside the target environment polls the Git repository for changes and pulls them in. The agent has access to the cluster; the CI system doesn't need access to production. This is how ArgoCD and Flux work in Kubernetes environments.

Which should you use?

Pull-based is more secure in theory — your CI/CD system never has production credentials, so a compromised pipeline can't directly attack production. It also handles drift correction naturally.

Push-based is simpler, works with any infrastructure (not just Kubernetes), and is what most teams already have in place. If you deploy to VPS servers, shared hosting, or cloud instances via SSH/SFTP, push-based is the practical choice.

The reality: most teams use push-based GitOps, and that's fine. The value of GitOps comes from using Git as the source of truth and automating deployments — not from the push/pull mechanism specifically.

GitOps Beyond Kubernetes

Most GitOps content assumes Kubernetes. But you don't need Kubernetes to do GitOps. If your workflow looks like this, you're already practicing GitOps principles:

  1. Your application code lives in Git
  2. Your server configuration or deployment scripts are in the same (or a linked) repository
  3. A push to main triggers an automated deployment
  4. You can rebuild your entire environment from what's in the repository
  5. You review infrastructure changes through pull requests, just like code changes

A developer pushing a WordPress theme update from Git to their server via DeployHQ is practicing push-based GitOps — Git is the source of truth, deployment is automated, every change is versioned and auditable.

What a non-Kubernetes GitOps setup looks like

repository/
├── src/                    # Application code
├── config/
│   ├── staging.env         # Environment-specific config
│   └── production.env
├── scripts/
│   ├── deploy.sh           # Deployment script
│   └── rollback.sh         # Rollback procedure
├── infrastructure/
│   ├── nginx.conf          # Server configuration
│   └── supervisor.conf     # Process manager config
└── .deployhq/              # DeployHQ build configuration

Everything needed to run the application is in the repository. A new developer can look at Git and understand the entire system — not just the code, but how it's configured, deployed, and operated. If the production server burns down, you can rebuild it from what's in the repo.

GitOps vs. DevOps vs. CI/CD

These terms layer on top of each other:

Concept What it is Scope
DevOps A philosophy — dev and ops collaborate, automate, share responsibility Culture + practices + tools
CI/CD A practice — automate building, testing, deploying software The delivery pipeline
GitOps An approach — Git is the single source of truth for everything Infrastructure + deployment management

CI/CD is one component of DevOps. GitOps is an approach to managing the infrastructure that CI/CD deploys to. You can do CI/CD without GitOps (by configuring servers manually), and you can do GitOps without full CI/CD (by deploying manually from Git). In practice, they work best together.

The GitOps Toolchain

For Kubernetes environments

  • Flux — CNCF graduated project. Lightweight, composable, built for Kubernetes-native GitOps. Watches Git repos and automatically applies changes to the cluster.
  • ArgoCD — CNCF graduated project. Provides a web UI for visualizing application state, managing multi-cluster deployments, and handling complex rollout strategies.

Both implement the pull-based model and handle continuous reconciliation natively.

For non-Kubernetes environments

  • DeployHQ — Connects to your Git repository and deploys to any server (VPS, shared hosting, cloud) via SSH/SFTP/S3. Supports build pipelines, zero-downtime deployments, and automatic deployments on push.
  • Ansible — Automation tool that can be triggered by Git changes to configure servers and deploy applications. Declarative-ish (playbooks describe desired state) but doesn't do continuous reconciliation.
  • TerraformInfrastructure as Code tool for provisioning cloud resources. Store your .tf files in Git, apply changes through a pipeline — that's GitOps for infrastructure.

Managing Secrets in GitOps

The biggest practical challenge: if everything is in Git, how do you handle secrets (API keys, database passwords, certificates)?

You never commit plaintext secrets to Git. Instead:

  • Sealed Secrets (Kubernetes) — Encrypt secrets so only the cluster can decrypt them. The encrypted version is safe to commit.
  • SOPS (Secrets OPerationS) — Mozilla's tool for encrypting specific values in YAML/JSON files. The file structure is visible, but sensitive values are encrypted.
  • External secret managers — HashiCorp Vault, AWS Secrets Manager, or your CI/CD tool's secret storage. The Git repository references the secret by name; the actual value is injected at deployment time.
  • Environment variables in your deployment toolDeployHQ and similar tools let you define environment-specific variables that are injected during deployment without being stored in the repository.

Common Mistakes

Storing everything in one massive repository. For small projects, a single repo works fine. For larger systems, separate repos for application code and infrastructure make reviews cleaner and allow different teams to own different pieces.

Skipping pull request reviews for infrastructure changes. The whole point of GitOps is that infrastructure changes go through the same review process as code. If someone can push directly to main and change server configuration without review, your GitOps workflow has a gap.

Manual changes in production. Every manual change creates drift between Git and reality. If you SSH into production and edit a config file, the next GitOps sync might overwrite it — or worse, the discrepancy goes undetected. Discipline matters: if it's not in Git, it doesn't happen.

Over-engineering for a small team. A 3-person team deploying a single application doesn't need ArgoCD, Flux, and a multi-cluster strategy. Git-triggered automatic deployments to your server is GitOps enough. Add complexity only when you have the problems that complexity solves.

FAQs

Do I need Kubernetes to use GitOps? No. GitOps principles (Git as source of truth, automated deployments, versioned infrastructure) apply to any environment. Kubernetes has the most mature tooling (ArgoCD, Flux), but any Git-triggered deployment workflow follows GitOps principles.

What's the difference between GitOps and Infrastructure as Code? Infrastructure as Code means defining infrastructure in code files. GitOps means storing those files in Git and using Git workflows (pull requests, reviews, automated sync) to manage changes. IaC is a prerequisite for GitOps — you need declarative config files before you can version-control them.

Can I use GitOps with FTP hosting? In principle, yes — if your deployment tool can deploy from Git to an FTP server automatically. Tools like DeployHQ support FTP/SFTP deployment triggered by Git pushes. You won't get continuous reconciliation, but you get versioned, automated deployments — which is the most valuable part of GitOps for most teams.

How does GitOps handle rollbacks? Since every state is a Git commit, rolling back means reverting to a previous commit. git revert creates a new commit that undoes the change, the automation detects it, and the system is restored to the previous state. This is one of GitOps's strongest features — your rollback strategy is built into your version control.


Ready to deploy from Git automatically? DeployHQ connects to GitHub, GitLab, and Bitbucket and deploys to any server on every push — with build pipelines, zero-downtime releases, and instant rollback. Start your free trial.

Have questions? Reach out at support@deployhq.com or find us on X (@deployhq).