+91 80401 38000[email protected]24/7 Expert Support
[email protected]Client Portal →
ServerGurus
← All posts
DevOpsTutorialKubernetes

How to Set Up GitOps with ArgoCD on Bare Metal Kubernetes

By ServerGurus15 July 20266 min read
How to Set Up GitOps with ArgoCD on Bare Metal Kubernetes

Here is the problem with most Kubernetes setups: someone runs kubectl apply from their laptop, the deployment works, and then nobody knows what is actually running in production because the YAML on the laptop is different from the YAML in the cluster. Two weeks later the same person runs kubectl apply from a different laptop and accidentally reverts a fix.

GitOps fixes this. Your Git repository is the single source of truth. ArgoCD watches the repo and syncs the cluster to match. Nobody runs kubectl apply directly. Every change goes through Git, which means every change is reviewed, logged, and rollback-able.

Here is how to set it up on a bare metal k3s cluster in under 30 minutes.

What You Will Build

By the end of this guide, you will have:

  • ArgoCD running on your k3s cluster
  • A Git repository connected as the source of truth
  • A sample application that auto-deploys when you push to Git
  • Automatic sync with a 3-minute polling interval
  • A web UI showing the health of every application

This works on any Kubernetes cluster. We tested it on a single-node k3s cluster on bare metal, but it scales to 100 nodes with zero changes.

Step 1: Install ArgoCD

ArgoCD ships as a single namespace of Kubernetes resources. Install it directly from the upstream manifest:

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Wait for all pods to be ready:

kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd-server -n argocd --timeout=120s

ArgoCD installs four core components: the API server, the repo server (clones Git repos), the application controller (syncs state), and Redis (caches). All of them run inside your cluster.

Step 2: Expose the ArgoCD UI

By default, the ArgoCD server is a ClusterIP service. Expose it via NodePort so you can access it from your browser:

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'

Get the NodePort and your node's IP:

export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}')
export ARGOCD_PORT=$(kubectl get svc argocd-server -n argocd -o jsonpath='{.spec.ports[0].nodePort}')
echo "ArgoCD: https://$NODE_IP:$ARGOCD_PORT"

Step 3: Get the Admin Password

ArgoCD generates an initial admin password stored in a Kubernetes secret:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

Log in at the URL from Step 2. Username: admin. Password: the output above. Change it immediately after login:

argocd account update-password

Step 4: Connect ArgoCD to Your Git Repository

Create a directory in your Git repo for Kubernetes manifests. The structure should look like this:

my-gitops-repo/
  apps/
    my-app/
      deployment.yaml
      service.yaml
      ingress.yaml

Now register this repo with ArgoCD:

argocd repo add https://github.com/your-org/my-gitops-repo.git

ArgoCD will clone this repo and watch for changes. If your repo is private, add an SSH key or personal access token:

argocd repo add [email protected]:your-org/my-gitops-repo.git --ssh-private-key-path ~/.ssh/id_rsa

Step 5: Create Your First Application

Define an ArgoCD Application that points to your manifests:

# argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/my-gitops-repo.git
    targetRevision: main
    path: apps/my-app
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

The syncPolicy.automated block is the important part. prune: true means ArgoCD deletes resources that you remove from Git. selfHeal: true means ArgoCD reverts any manual changes made directly in the cluster. Your Git repo becomes the only way to change production.

Apply it:

kubectl apply -f argocd-app.yaml

ArgoCD will immediately clone your repo, create the resources defined in apps/my-app/, and begin monitoring for changes.

Step 6: Verify Sync

Open the ArgoCD UI. You should see your application with a green "Synced" status. If it shows "OutOfSync," click the app, then click "Diff" to see what changed between Git and the cluster.

Make a change to your deployment.yaml in Git and push it:

sed -i 's/replicas: 1/replicas: 3/' apps/my-app/deployment.yaml
git add . && git commit -m "scale to 3 replicas" && git push

Within 3 minutes, ArgoCD will detect the change and scale your deployment to 3 replicas. No kubectl apply. No SSH. No manual intervention.

What Makes GitOps Better Than kubectl apply

Every change is audited. Git history shows who changed what and when. If a deployment breaks at 2:14 PM, you run git log and see exactly which commit caused it.

Rollback is one command. git revert <bad-commit> && git push. ArgoCD syncs the reverted state. No need to find the old YAML file on someone's laptop.

No configuration drift. ArgoCD self-heals every 3 minutes. If someone manually scales a deployment from 3 replicas to 10, ArgoCD reverts it back to what is in Git. Your cluster always matches your repo.

Pull requests become deployment approvals. Require PR reviews on your GitOps repo. ArgoCD deploys only after the PR is merged. This is the cheapest compliance audit trail you will ever set up.

When GitOps Makes Sense (and When It Does Not)

GitOps works best for infrastructure and applications that change at human speed: deployments, services, ConfigMaps, Ingress rules, RBAC policies. If it lives in YAML and changes when you make a decision, it belongs in GitOps.

GitOps is not great for things that change at machine speed: autoscaling events, pod restarts, cron job executions. Those are operational events, not configuration changes. Let Kubernetes handle them natively.

For most teams running 5 to 50 microservices, GitOps with ArgoCD replaces the entire deployment workflow. No CI/CD pipeline that runs kubectl apply as a deploy step. No deployment scripts. No manual rollbacks. Just Git.

Bare Metal Makes GitOps Simpler

On a managed Kubernetes service like EKS or GKE, you have an additional layer of infrastructure (node groups, IAM roles, networking) that also needs to be managed somehow. That usually means Terraform plus GitOps, and now you have two sources of truth to keep in sync.

On bare metal k3s, your cluster is your servers. You install k3s once. You install ArgoCD once. From that point forward, everything is Git. No Terraform state files. No cloud provider drift. No IAM policies that someone changed in the console and forgot to commit.

This simplicity is why teams running production Kubernetes on bare metal report fewer deployment incidents than teams on managed Kubernetes. Fewer moving parts means fewer things that can go out of sync.

How ServerGurus Helps

Our bare metal servers come with k3s pre-installed if you want it. Our DevOps team can set up ArgoCD, connect it to your Git repos, and hand you a working GitOps pipeline before lunch. After that, your team pushes code. ArgoCD handles the rest.

No managed Kubernetes surcharges. No per-cluster fees. Just dedicated servers running your infrastructure, your way.

Talk to our DevOps team about GitOps setup or see bare metal server plans.

Ready to build your infrastructure?

Get a quote from our Hyderabad-based team - Tier IV datacenter, real support, INR or USD billing.

View pricingRequest a quoteWhatsApp sales