Cloud-native infrastructure is all about performance, adaptability, and resilience– all that GitOps can offer. GitOps is a methodology that applies Infrastructure as a Code (IaC) principles to Continuous Deployment (CD) and operations. Before GitOps, IaC existed independently.
GitOps follows a declarative approach where it uses Git as a single source of truth— meaning Git serves as an authoritative and version-controlled repository for all infrastructure and application deployments. It also improves deployment speed and reliability a lot– as much as 50% reduction in deployment time.
Before GitOps, deployments were often prone to configuration drifts, security risks, and complex rollbacks due to undocumented manual updates such as ad-hoc hotfixes or direct changes through the cloud’s console. More problems arose when companies had to scale their project across multiple clusters, requiring ad-hoc scripts and workarounds.

GitOps is not an experimental trend now–it's a widely adopted best practice for cloud-native infrastructure, automating deployments and regulating consistency. GitOps tools like ArgoCD, FluxCD, and Jenkins X make implementing GitOps easier, helping organizations deploy infrastructure scale Kubernetes workloads efficiently while maintaining full control.
Understanding GitOps Tools & Their Core Principles
The GitOps method stores application and infrastructure as code in Git repositories, which automation tools implement for target environment deployment.
GitOps strongly recommends version control, which enables a complete and transparent audit trail of all changes for people who have permission to review.
Let’s understand the major principles that GitOps works on:
- Declarative Infrastructure as Code (IaC)
- Automated Reconciliation: Continuous Sync with the Cluster
- Drift Detection & Automated Rollbacks
- Flexibility & Security
GitOps vs Release Management?
Many developers often confuse GitOps with release management. While GitOps automated deployments, release management involves approvals, progressive rollouts, and governance - areas where enterprise tools like Spinnaker shine. GitOps and release management complement each other rather than compete.
Prerequisite: Setting Up Kubernetes in Docker Desktop
To get started, let’s make sure that you have Docker on your system. We are using Kubernetes in Docker; you can also use minikube along with Docker. Also, Docker Desktop has a built-in Kubernetes feature, so you don’t need Minikube.
For enabling GitOps Kubernetes in Docker Desktop:
- Open your Docker Desktop.
- Click on Settings and then go to Kubernetes. Here, enable the toggle and then click on the ‘Apply and Restart’ button.
- Wait for some time and use the command kubectl cluster-info to check if it’s running.
Output:
kubectl cluster-info
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. echoindia@ECHOs-MacBook-Air-
Kubernetes control plane is running at https://127.0.0.1:6443 CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns dns/proxy
Setting Up GitOps with ArgoCD
ArgoCD is one of the best GitOps tools that provides users with a UI-driven approach to automate Kubernetes deployments. It does this by continuously syncing Git with the cluster. You can use Helm, Kustomize and raw YAML, which makes it quite flexible even for complex deployments. Let’s have a look at how to set up ArgoCD GitOps platform:
Step 1: Install ArgoCD
Now that you have your kubernetes running, the first thing is to install the ArgoCD. You can either apply the manifest directly or use Helm ( better version control).
- Option 1: Install ArgoCD using Helm Chart
Helm provides better customization and flexibility. For using ArgoCD helm chart, you need to use the following commands:
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd --namespace argocd --create-namespace
- Option 2: Install ArgoCD using YAML Manifests
Open your terminal and then copy this command:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Output:
kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifest
s/install.yaml
namespace/argocd created customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created serviceaccount/argocd-application-controller created
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
serviceaccount/argocd-applicationset-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-notifications-controller created
serviceaccount/argocd-redis created serviceaccount/argocd-repo-server created
serviceaccount/argocd-server created role.rbac.authorization.k8s.io/argocd-application-controller created role.rbac.authorization.k8s.io/argocd-applicationset-controller created role.rbac.authorization.k8s.io/argocd-dex-server created role.rbac.authorization.k8s.io/argocd-notifications-controller created role.rbac.authorization.k8s.io/argocd-redis created
You can verify if it’s installed properly. Just run this command: kubectl get pods -n argocd
If the pods aren’t in Running state, check their logs and describe the pod to address the issue:
kubectl logs -n argocd <pod-name>
kubectl describe pod -n argocd <pod-name>
Here, you have to change the <pod-name> with your pod.
Step 2: Post Forward ArgoCD Server
Now, we will expose the ArgoCD UI by running the following command:
kubectl port-forward svc/argocd-server -n argocd 8080:443
You can use any other port. The port will start running at https://localhost:8080, and you can access the ArgoCD UI at this port.
Note: This method only exposes the UI locally. For production environments, it is recommended to set up Ingress or LoadBalancer services instead of relying on port forwarding.
Output:
kubectl port-forward svc/argocd-server -n argocd 8080:443
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
Handling connection for 8080

Step 3: Get the Initial Admin Password
Your port is running successfully, but you need to log in to the ArgoCD UI. You can get the password by using this command in your terminal:
kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode
Use admin as the username and this password to log in. The UI will look something like this:

You can connect your git repo and then get started after this.

Step 4: Create your App and Make your First Deployment with ArgoCD
With Argo CD successfully set up, you can now create and deploy your applications using declarative GitOps principles. Define your application manifests in a Git repository, connect it to Argo CD, and automate deployments seamlessly.
Setting Up GitOps with FluxCD
If you want ArgoCD alternatives that are more lightweight than FluxCD is the one. FluxCD follows a pull deployment model that helps to reduce external access to the cluster, improving security. However, FluxCD still needs some access mechanisms like Webhook Triggers. Let’s see how you can set up FluxCD:
Important prerequisites other than Kubernetes:
- A GitHub repository – This is for storing and managing Kubernetes manifests.
- GitHub Personal Access Token (PAT) – With repository access for authentication.
Step 1: Installing Flux CLI
To get started, we will need GitOps Flux CLI installation first. I am using MacOS here; you can see other commands too:
For macOS (Homebrew)
brew install fluxcd/tap/flux
For Linux
curl -s https://fluxcd.io/install.sh | sudo bash
For Windows (Using Chocolatey)
curl -s https://fluxcd.io/install.sh | sudo bash
choco install fluxcd
For checking if Flux CLI is successfully installed, use flux --version
Output:
brew install fluxcd/tap/flux
==> Auto-updating Homebrew... Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see man brew').
==> Homebrew collects anonymous analytics.
Read the analytics documentation (and how to opt-out) here: https://docs.brew.sh/Analytics No analytics have been recorded yet (nor will be during this 'brew' run).==> Homebrew is run entirely by unpaid volunteers. Please consider donating: https://github.com/Homebrew/brew#donations
==> Auto-updated Homebrew! Updated 1 tap (homebrew/core).
==> New Formulae cloudfoundry-cli
You have 6 outdated formulae installed.Tapping fluxcd/tap
Cloning into '/opt/homebrew/Library/Taps/fluxcd/homebrew-tap'
remote: Enumerating objects: 690, done.
remote: Counting objects: 100% (229/229), done. remote: Compressing objects: 100% (146/146), done.
remote: Total 690 (delta 119), reused 170 (delta 83), pack-reused 461 (from 1) Receiving objects: 100% (690/690), 104.93 KiB | 1.69 MiB/s, done.
Resolving deltas: 100% (342/342), done. Tapped 7 formulae (22 files, 156.5KB).
==> Fetching fluxcd/tap/flux
Step 2: Bootstrap Flux into Your Kubernetes Cluster
Next, we need to set up the environment variables for GitHub authentication. For this, you need to copy these commands and paste into your terminal:
You have to change the <your-token> and <your-github-username> with yours respectively.
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-github-username>
Now, bootstrap Flux will connect with your GitHub repository. Use this command:
flux bootstrap github \
--owner=$GITHUB_USER \
--repository=FluxCD \
--branch=main \
--path=fluxCdCluster \
--personal
Output:
flux bootstrap github --owner=shiw0712echo
--repository=ArgoCD --branch=main
--path=clusters/my-cluster -personal
connecting to github.com
cloning branch "main" from Git repository "https://github.com/shiw0712echo/ArgoCD.git"
cloned repository generating component manifests
generated component manifests
committed component manifests to "main" ("6ad6d413993ac2952ff97566569c3e378e6bf509") pushing component manifests to "https://github.com/shiw0712echo/ArgoCD.git
The path here is the location of your yaml files. You can create your own directory and use that in this path. This command will install Flux system components in Kubernetes and start syncing configurations from your Git repo.
Step 3: Configure Git Repository Source
We’ll need a git repository definition to fetch the manifest from your repo. For this, you need to create a gitrepository.yaml file inside your repository.
I’m using my repo FluxCD to carry this out.
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: FluxCD
namespace: flux-system
spec:
interval: 1m
url: https://github.com/shiw0712echo/ArgoCD.git
ref:
branch: main
secretRef:
name: flux-system
Change the name and the URL of your github repo.
Note: If your repo is private, We need a secret for authentication. The secretRef can be removed if your repo is public.
Create it using this command:
kubectl create secret generic flux-system \
\
--namespace=flux-system \
--from-literal=username=<your-github-username>
--from-literal=password=<your-github-token>
Replace <your-github-userName> and <your-github-token> with your own github username and github token here.
Output:
kubectl create secret generic flux-system
--namespace=flux-system --from-literal=username=shiw@712echo
--from-literal=password=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
secret/flux-system created
Step 4: Define Kubernetes Manifests in GitHub
Next, we need to define the Kubernetes manifest in our github repository. We do this because Flux applies Kubernetes configurations stored in a Git repo. Let’s see how to organize the structure accordingly.
Now you need to define Kustomization, service, and example deployment inside the path=fluxCdCluster as defined earlier.
- Create service.yaml file:
apiVersion: v1
kind: Service
metadata:
name: flux-app
namespace: default
spec:
selector:
app: flux-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
- Create deployment.yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: flux-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: flux-app
template:
metadata:
labels:
app: fluxCd-app
spec:
containers:
- name: flux-app image: nginx
ports:
- containerPort: 80
Commit these changes and push it to your git repo. Next, we’ll create a Kustomization resource that tracks and applies the manifests.
- Kustomization.yaml file
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
Now, you need to apply this configuration:
kubectl apply -f kustomization.yaml
Check if Flux is successfully connected to your repo. Use this command:
flux get kustomizations
Output:
If your output shows READY=True, then your connection is successful.
Step 5: Verify Deployment
To check if your connection is successful, check if the pods are running:
kubectl get pods -A
Output:
Now check the service:
kubectl get svc
If the pod is running, Flux CD has successfully deployed your application.
Output:|
kubectl port-forward svc/my-app-service 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
Handling connection for 8080
Your service is of type ClusterIP i.e, it is accessible only inside the cluster. So, you need to port-forward it to access it from your local machine:
Use this command:
kubectl port-forward svc/fluxCD-app 8080:80
You can change the port number as per your preference. Now open your browser and visit http://localhost:8080. If your application is running, you’ll see the UI or the response like this :

You have now successfully set up FluxCD and deployed your first application!
Setting Up GitOps with Jenkins X
Jenkins X is primarily a CI/CD tool that uses GitOps, automating both deployments and environment promotions via Git. It focuses more on CI/CD workflows and integrates with Tekton pipelines, creating preview environments for pull requests and reducing manual interventions, making it a great choice for teams needing full GitOps automation. Let’s see how to set it up.
Step 1: Install Jenkins X
To install the latest version of Jenkins X, use this command in your terminal:
- MacOs
brew install --no-quarantine --cask jenkins-x/jx/jx
- Linux
curl -L https://github.com/jenkins-x/jx/releases/download/v3.11.52/jx-linux-amd64.tar.gz | tar xzv
chmod +x jx
sudo mv jx /usr/local/bin
- Windows
Click on this link (downloading a binary).
Then, copy the jx binary to any directory of your choice on your $PATH.
You can check it by using the command jx version.
Output:
version: 3.11.52
shaCommit: 83bca73eb044c9114aaca12854d789e5676049c2
buildDate: Wed Feb 19 15:37:33 UTC 2025
goVersion: 1.23.2
branch: main
gitTreeState: clean
Step 2: Install Git Operator
Since we are using Jenkins X 3.x, it uses a git operator that manages all the installing and upgrading of Jenkins X or any other environment components.
jx admin operator
This will:
- Install Jenkins X components in your Kubernetes cluster.
- Set up GitOps Pipelines for CI/CD.
Make sure you have a Github token. If not, please generate one from here.
Output:
git clone URL is https://github.com/shiw0712echo/JenkinsXCreate.git
now verifying we have a valid git username and token so that we can clone the git repository inside kubernetes…
? Enter Bot Git username the Kubernetes operator will use to clone the environment git repository shiw0712echo
WARNING: validation failures in YAML file /Users/echoindia/Desktop/ArgoCD/jenkins-x-boot-config/JenkinsXCreate/jx-requirements.ym
1: (root): Additional property gitops is not allowed, cluster: Additional property gitUrl is not allowed To work with git provider https://github.com we need an API Token Please click this URL and generate a token
https://github.com/settings/tokens/new?scopes=repo,read:user,read:org,user:email,admin:repo_hook,delete_repo,write:packages,read:
packages,write:discussion,workflow
Then COPY the token and enter it below:
? Enter Bot Git token the Kubernetes operator will use to clone the environment git repository [? for help] ************ git username is shiw0712echo for URL https://github.com/shiw0712echo/JenkinsXCreate.git and we have a valid password running command:
/Users/echoindia/.jx3/plugins/bin/helm-3.6.2 upgrade --install \
-set url=https://github.com/****/JenkinsXCreate.git \
-set username=**** \
-set password=**** --namespace jx-git-operator --create-namespace jxgo jxgh/jx-git-operator
waiting for the Git Operator to be ready in namespace jx-git-operator... pod jx-git-operator-7565dc5649-wq77j has status Pending pod jx-git-operator-7565dc5649-wq77j has status Ready the Git Operator is running in pod ix-ait-operator-7565dc5649-wa77÷
waiting for boot Job pod with selector app=ix-boot in namespace ix-qit-operator…
Now, to check if the installation is successful, let’s verify it using the command: kubectl get pods -n jx
If it's in Running Status, then we are good to go.

Step 4: Access Jenkins X
To launch the Jenkins X UI in our browser, we need to run our next command:
jx UI
If the UI doesn’t open, check the port and forward it. Then, access http://localhost:8080 in your browser.
kubectl port-forward svc/jx-pipelines-visualizer 8080:80 -n jx
Step 5: Create & Deploy a Project
We have installed and run Jenkins X UI successfully. You can now create your projects and deploy them easily. Jenkins X automates CI/CD pipelines for your applications. Use this command to create a new project:
jx project create
Follow the on-screen prompts to set up a Git repository and initialize a project.
Then, to deploy a sample app:
jx create quickstart
This action will generate the code, push it to GitHub, and trigger an automated CI/CD pipeline. You are good to go now!
Best Practices for Production Deployments
When you're setting up GitOps tools, you also have to ensure that it's free from any vulnerabilities.
This keeps the system protected and helps us scale our product whenever needed. Here are some GitOps best practices that should be followed for production deployments:
Security
GitOps workflows need strong security measures. Teams should implement RBAC in ArgoCD and FluxCD to ensure that users have only the necessary permissions. Some more security measures that teams can use are:
- Git commit signing (GPG)- to verify code authenticity, preventing unauthorized access.
- SOPS (Secrets OPerationS), Sealed Secrets, or HashiCorp Vault- to encrypt sensitive data
- Kubernetes NetworkPolicies- for network security enforcement to restrict pod-to-pod communication.
- Audit Logging- to track all changes and track suspicious activity in deployments.
Flexibility
It's obvious that the infrastructure will grow at some point. As this happens, it becomes important to manage multiple clusters and teams efficiently. You can use ArgoCD’s ApplicationSet or FluxCD’s Cluster API to automate multi-cluster deployments.
And for multi-tenancy and multiple environments, teams can enforce namespace-based RBAC and make use of kustomize overlays to manage environment-specific configurations.
Monitoring
Workability depends on how well you can monitor your GitOps system. Connect Prometheus and Grafana to monitor deployment status and detect both system health problems and syncing difficulties instantly.
ArgoCD will send you notifications through Slack, Teams, or email to fix deployment problems immediately. You can trace and resolve system problems better through gathered data stored in Elasticsearch or Loki services.
Now, tools like ArgoCD and FluxCD automate deployments and enforce consistency, but they also introduce a lot of friction. Making even a small change - like adjusting resource limits, updating an environment variable, or scaling replicas - often means modifying your YAML configurations, committing changes to Git, and waiting for reconciliation. This works well for large-scale deployment automation, but it slows DevOps teams down when they need quick, controlled updates without breaking any GitOps workflows.
Kapstan: A Much More Simpler Way to Manage Your GitOps Deployments
Kapstan bridges this gap. Instead of forcing developers and DevOps engineers to interact solely through Git and Kubernetes manifests, it provides a UI-driven experience that automates deployments, scaling, and configuration management, all while keeping Git as the source of truth. It doesn’t replace ArgoCD or FluxCD but simplifies everyday operations, allowing teams to move faster without bypassing any GitOps principles.
The process of deploying a containerized service with Kapstan is pretty simple. Instead of writing YAML or scripting kubectl commands, a service can be created directly from the Kapstan’s UI.
The user starts by selecting Container Service, entering details like the image repository, tag, and optional startup commands, and clicking Confirm.

Unlike traditional GitOps tools, where changes need to be committed and reconciled separately, Kapstan applies configurations automatically while still maintaining version control.

Once the container service is defined, scaling and resource allocation are just as easy. Kapstan allows teams to configure CPU limits, memory allocation, and scaling preferences without modifying Kubernetes manifests. Users can choose manual scaling or enable auto-scaling, ensuring workloads adjust dynamically based on demand. Readiness and liveness probes can also be configured directly in the UI, helping ensure smooth rollouts without editing YAML configuration files.

With everything configured, deployment is just one click away. Kapstan provides the service, applies GitOps-friendly changes, and immediately provides monitoring insights. Logs, metrics, and deployment history are accessible in the same interface, reducing the need to switch between multiple tools. If an update is needed, changes can be applied through the UI and automatically synced to Git, ensuring the GitOps model remains intact without unnecessary complexity.

For teams that want GitOps without constant YAML interaction, Kapstan is a practical alternative. It enables developers to self-serve deployments and configurations while maintaining governance and security. Instead of slowing down operations with manual Git commits for every small change, teams can move fast while still keeping GitOps principles intact. It’s not about replacing ArgoCD or FluxCD - it’s about making them more usable for day-to-day work.
To learn more about Kapstan’s capabilities, check out its documentation.
Conclusion
GitOps tools like ArgoCD, FluxCD, and others have revolutionized infrastructure and application management by enabling continuous delivery of automated, version-controlled deployments. By leveraging Git as the single source of truth, these tools ensure consistency, security, and scalability in modern DevOps workflows.
Frequently Asked Questions
- What is the major advantage of GitOps?
The major advantage of GitOps is that it provides a declarative and automated approach to infrastructure management and application management, ensuring consistency, reliability, and easy rollbacks using Git as the single source of truth.
- What is GitOps vs DevOps?
GitOps is a subset of DevOps that focuses on using Git as the central control mechanism for managing infrastructure and deployments, while DevOps is a broader practice that combines development and operations to streamline the software development lifecycle and delivery.
- What are the three core practices of GitOps?
The three core practices of GitOps are declarative infrastructure configuration (defining infrastructure as code), version control with Git (storing all changes in Git), and automated reconciliation (ensuring the actual state matches the desired state).
- Is GitHub Actions GitOps?
GitHub Actions can be part of a GitOps workflow but is primarily a CI/CD automation tool. GitOps requires continuous reconciliation, which is typically handled by tools like ArgoCD or Flux.
- Is GitOps a CI/CD tool?
No, GitOps is a methodology, not a tool. It leverages CI/CD tools but focuses on declarative configuration and automated reconciliation to maintain the desired state of infrastructure and applications.
- Can I use GitOps for non-Kubernetes environments?
Yes, while GitOps is widely used for Kubernetes, it can also be applied to non-Kubernetes environments, such as cloud native applications managing cloud infrastructure, databases, or VMs, using tools like Terraform or Pulumi.