Kubernetes applications in production traditionally require manual work and time.GitOps with Argo CD solves this. It keeps your cluster in sync with git, where your repository defines the desired state. Argo CD makes sure the cluster always matches it, and when something falters, it fixes itself automatically. With GitOps, your applications become self-healing and always stay in sync with git.What Is GitOps and Self-Healing?GitOps means your git repository is the single source of truth for everything. When reality doesn’t match git, the system automatically fixes itself.Your app’s configurations are stored in git, and any changes to either your app or the git source code will automatically be fixed. This is GitOps at its finest and most simple opportunity to accelerate the traditional deployment process.Rejuvenating Traditional DeploymentWhen you follow the traditional deployment process, there are many scenarios where things might take an unexpected turn:Someone can manually change the production settings, and your production might halt.A technical misstep on the server can pause production, then you have to manually restart it.Your app configuration changes, and you have to keep track of what was changed.GitOps handles all these possibilities effectively and with simplicity.GitOps Self-Healing SolutionWith GitOps, you can maintain the current state of your application in a git repository. GitOps tech like Argo CD ensures that whatever is defined in your git matches the actual app deployment.If there are technical hiccups on the server, GitOps will automatically resolve them and restore your app to the defined state. This is known as self-healing in GitOps.On top of that, you also keep an audit trail of all the changes made in git.Step 0: PrerequisitesDocker is installed on your system.My go-to: WSL2 with Ubuntu. Feel free to use your own Linux setup.GitHub account.Docker Hub account.My go-to: React project (You can use any project).Knowledge of Kubernetes (optional).Step 1: Install and Start MinikubeFirst, set up a Kubernetes cluster. For this tutorial, we will use Minikube. It’s lightweight and ideal for learning.(You can skip this step if you already have a cluster running locally.)Install MinikubeRun the commands below to install Minikube:# Download and install minikubecurl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64sudo install minikube-linux-amd64 /usr/local/bin/minikube# Install kubectl if you don't have itcurl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl# Note: Some Linux distributions need this for Minikubesudo apt install conntrackStart Minikube ClusterBefore running the command below, make sure Docker is running.# Start minikube with Docker driverminikube start --driver=docker# Verify everything is workingkubectl version --clientkubectl get nodes# You should see:# NAME STATUS ROLES AGE# minikube Ready control-plane 1m# Enable ingress addon (useful for later)minikube addons enable ingressStep 2: Create Your React App# Create the appcd ~/projectsnpx create-react-app my-selfhealing-appcd my-selfhealing-appUpdate the App for DemoReplace src/app.js:import './App.css';import { useState, useEffect } from 'react';function App() { const [count, setCount] = useState(0); const [timestamp, setTimestamp] = useState(''); useEffect(() => { setTimestamp(new Date().toLocaleString()); }, []); return ( <div className="App"> <header className="App-header"> <h1>๐ก๏ธ Self-Healing React App</h1> <p>This app automatically fixes itself using GitOps!</p> <div style={{ background: 'rgba(255,255,255,0.1)', padding: '20px', borderRadius: '10px', margin: '20px 0' }}> <button onโClick={() => setCount(count + 1)} style={{ padding: '10px 20px', fontSize: '16px', backgroundColor: '#61dafb', border: 'none', borderRadius: '5px', cursor: 'pointer' }} > Clicked {count} times </button> </div> <div style={{ fontSize: '14px', opacity: 0.8 }}> <p>๐ Auto-sync enabled</p> <p>๐ ๏ธ Self-healing active</p> <p>๐ Deployed: {timestamp}</p> <p>๐ท๏ธ Version: 1.0.0</p> </div> </header> </div> );}export default App;Note: This code should work fine. You can also use Vite or any other framework, since CRA is deprecated.Create DockerfileA Dockerfile is used to write the Docker codebase.Create Dockerfile:Make sure to put this file in the root of the project. Paste the code below into it.FROM node:18-alpine as builderWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run buildFROM nginx:alpineCOPY --from=builder /app/build /usr/share/nginx/htmlEXPOSE 80CMD ["nginx", "-g", "daemon off;"]Here, we are first installing the node, then creating a build, then following instructions on running the application on port 80.Push to GitHubOnce all your code is ready, push it to GitHub.git initgit add .git commit -m "Initial self-healing app"git branch -M maingit remote add origin https://github.com/YOUR_USERNAME/my-selfhealing-app.gitgit push -u origin mainStep 3: Build and Push Docker ImageNow that the code is ready, create a Docker image and push it to Docker Hub.If you don’t have a Docker Hub account, you can sign up and create one from the Docker Hub page.Also, make sure Docker is running locally. If you don’t have Docker installed locally, you can install Docker Desktop.# Build the imagedocker build -t YOUR_DOCKERHUB_USERNAME/selfhealing-app:v1.0.0 .# Push to DockerHubdocker logindocker push YOUR_DOCKERHUB_USERNAME/selfhealing-app:v1.0.0Step 4: Create GitOps Configuration RepositoryTo get started with GitOps, create a new git repository. This is important because it’s possible to have separate repositories for source code and GitOps.# Build the imagedocker build -t YOUR_DOCKERHUB_USERNAME/selfhealing-app:v1.0.0 .# Push to DockerHubdocker logindocker push YOUR_DOCKERHUB_USERNAME/selfhealing-app:v1.0.0Create Kubernetes ManifestsFirst, create a new folder called “app.” Inside this folder, create Kubernetes-related files.Create app/deployment.yaml:apiVersion: apps/v1kind: Deploymentmetadata: name: selfhealing-app namespace: defaultspec: replicas: 2 # We are having 2 replicas of our app selector: matchLabels: app: selfhealing-app template: metadata: labels: app: selfhealing-app spec: containers: - name: react-app image: YOUR_DOCKERHUB_USERNAME/selfhealing-app:v1.0.0 # Update this! ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "50m" limits: memory: "128Mi" cpu: "100m"This is a regular Kubernetes deployment file with basic details. Make sure to update the image with your Docker image.Next, create another file for the Kubernetes service.Create app/service.yaml:apiVersion: v1kind: Servicemetadata: name: selfhealing-app-service namespace: defaultspec: selector: app: selfhealing-app ports: - port: 80 targetPort: 80 type: LoadBalancerCommit GitOps ConfigurationOnce all the files are created, push the changes to GitHub.git add .git commit -m "Add GitOps configuration for self-healing app"git push origin mainStep 5: Install Argo CDNext, install the tool that makes self-healing possible.# Create Argo CD namespacekubectl create namespace Argo CD# Install Argo CDkubectl apply -n Argo CD -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml# Wait for it to be ready (takes 2-3 minutes)echo "Installing Argo CD... this takes a few minutes"kubectl wait --for=condition=available --timeout=300s deployment/Argo CD-server -n Argo CDAccess Argo CD# Get the admin passwordecho "Argo CD Password:"kubectl -n Argo CD get secret Argo CD-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo# It will give output something like this. Keep the password handy. Username is admin.# Argo CD Password:#Gvy5q5gb3kADdS3w# Start port forwarding (keep this running)kubectl port-forward svc/Argo CD-server -n Argo CD 8080:443 > /dev/null 2>&1 &echo "Argo CD UI: https://localhost:8080"Now Argo CD will run on port 8080. Open this URL in your browser: https://localhost:8080.You would see a login screen like this:AgroCD login screen.You can use the username “admin” and the password that you have just generated using the above command. Once the login is done, it’s time to create an application inside Argo CD.Step 6: Create Self-Healing ApplicationTell Argo CD to manage your app and enable self-healing.Create Argo CD ApplicationCreate selfhealing-application.yaml:apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: selfhealing-app namespace: Argo CDspec: project: default source: repoURL: https://github.com/YOUR_USERNAME/my-GitOps-config # Update this! targetRevision: HEAD path: app destination: server: https://kubernetes.default.svc namespace: default syncPolicy: automated: prune: true # Remove extra resources selfHeal: true # THE MAGIC: Auto-fix when things driftApply it:# Update the repoURL first, then:kubectl apply -f selfhealing-application.yaml# This will give the result below# application.argoproj.io/selfhealing-app configuredOnce this is done, you should see your application in your Argo CD dashboard.Argo CD UI showing that it is running locally.Step 7: Access Your Self-Healing App# Check pods are runningkubectl get pods -l app=selfhealing-appIt should show something like this:Output showing that pods are running.# Access your app using port-forwardkubectl port-forward svc/selfhealing-app-service 3000:80 > /dev/null 2>&1 &Visit http://localhost:3000 to see your app running.Initial app with first version.Step 8: Test Self-Healing It’s time to test the changes and see the self-healing process in action.Deleting a PodStart by simply deleting a pod.# See your podskubectl get pods -l app=selfhealing-app#You should see 2 pods#NAME READY STATUS RESTARTS AGE#selfhealing-app-58cb69c845-ndssn 1/1 Running 1 (47m ago) 43h#selfhealing-app-58cb69c845-swsf6 1/1 Running 1 (47m ago) 43h# Delete one podkubectl delete pod -l app=selfhealing-app# Watch it get recreated immediatelykubectl get pods -l app=selfhealing-app#Now, even after deleting your pods, you will still see 2 pods.This is basic Kubernetes behavior, but now let’s see Argo CD’s self-healing …Delete the Entire DeploymentNow, go one step further by deleting everything.# The ultimate test - delete everything!kubectl delete deployment selfhealing-appkubectl delete service selfhealing-app-service# Watch Argo CD recreate everything automaticallykubectl get all -l app=selfhealing-app -wArgo CD app status, showing sync time and other details.The Argo CD dashboard will show sync time as “a few seconds ago.” This shows that it has already synced and created the application again. In other words, Argo CD ensures reality always matches git.Step 9: Making Real Updates (The GitOps Way)Now, make a legitimate change to see how GitOps handles updates.Update Your AppEdit src/App.js and change:๐ท๏ธ Version: 2.0.0 - Updated via GitOps!This update reflects a new version of the app. A simple change.Build and Push New VersionNow, create a new Docker build and push it to the Docker Hub. Also, push the source code to GitHub.cd ~/projects/my-selfhealing-app# Build and push new versiondocker build -t YOUR_DOCKERHUB_USERNAME/selfhealing-app:v2.0.0 .docker push YOUR_DOCKERHUB_USERNAME/selfhealing-app:v2.0.0# Commit app changesgit add .git commit -m "Update to version 2.0.0"git push origin mainUpdate GitOps ConfigurationNext, open the GitOps repository and use the update app/deployment.yaml file, updating the image path in the app/deployment.yaml file for the new Docker image.image: YOUR_DOCKERHUB_USERNAME/selfhealing-app:v2.0.0Next, push changes to the GitOps repo.# Commit the configuration changegit add .git commit -m "Deploy version 2.0.0"git push origin mainWatch Automatic DeploymentWithin minutes, Argo CD will:Notice the git repository changed.Pull the new configuration.Update the running application.Show “Synced” status in the UI.By default, Argo CD checks for changes every three minutes. You can adjust this to make it check faster (near real time) or slower (less frequent).Visit http://localhost:3000 to see your updated app.Make sure to do port forwarding before checking.kubectl port-forward svc/selfhealing-app-service 3000:80 > /dev/null 2>&1 &Now, you will see the updated UI.Final app showing self-healed state with new version.This screen means you have completed the GitOps setup. Now your apps will automatically be deployed and heal themselves whenever needed.Understanding the Self-Healing MagicHere’s the workflow that makes self-healing possible: Argo CD keeps watching the git repository. It also watches your Kubernetes cluster.It continuously compares the configuration defined in git and the actual Kubernetes structure.If it finds a difference, it signals Kubernetes to adjust as defined in git.This is the self-healing process.Image showing GitOps workflow.GitOps Is the Future (And Present)Every time you push to git, your app updates. When production stops, your app heals itself. This is more than deployment automation. It is a self-healing infrastructure. It takes care of itself while giving you back time to work on other things. That’s the power of GitOps.The post Make Your Kubernetes Apps Self-Heal With Argo CD and GitOps appeared first on The New Stack.