Production-Ready GitOps

Kubernetes
GitOps Lab

A production-style platform showcasing modern DevOps practices. Built with GitOps principles, automated CI/CD pipelines, and security-first design.

Live Auto-deployed by ArgoCD
terminal
# Deploy in one command
kubectl apply -f bootstrap/

# Everything else is automatic
argocd app get guestbook

# Status
✓ Synced   ✓ Healthy
0
Manual Deploys
100%
Git-Managed
<3m
Deploy Time
HTTPS
Auto-Renewed TLS

How It Works

Every component is designed for production reliability and security.

Container

Nginx Alpine serving static content with production-hardened security context.

non-root read-only FS resource limits
GitOps Pipeline

Push code to Git. CI builds the image. ArgoCD syncs to the cluster. Zero manual steps.

GitHub Actions GHCR Image Updater
Security

RBAC via AppProject, TLS via Let's Encrypt, pod security context, automated cert renewal.

AppProject RBAC cert-manager self-healing

Deployment Flow

How code reaches production in under 3 minutes.

1
Code Push

Developer pushes changes to GitHub main branch

2
CI Build

GitHub Actions builds Docker image, pushes to GHCR with SHA + latest tags

3
Image Detection

ArgoCD Image Updater detects new tag in container registry

4
Git Update

Image Updater commits new tag to kustomization.yaml in Git

5
GitOps Sync

ArgoCD detects Git change, syncs new manifests to K3s cluster

Tech Stack
OrchestrationK3s
GitOps EngineArgoCD
CI/CDGitHub Actions
Container RegistryGHCR
Ingress ControllerNGINX
TLS Certificatescert-manager
Manifest ToolKustomize
Image UpdatesImage Updater

Production Features

Built with best practices from day one.

Health Probes
Liveness & readiness checks for zero-downtime deploys
Resource Limits
CPU & memory boundaries to prevent resource exhaustion
HTTPS
Auto-renewed TLS certificates via Let's Encrypt
Self-Healing
ArgoCD auto-reverts manual changes to match Git
Pod Security
Non-root, read-only FS, dropped capabilities
AppProject RBAC
Scoped permissions for repos and destinations
Auto Deploy
Push code, Image Updater handles the rest
Audit Trail
Every change is a Git commit with full history

Step-by-Step Workflow

How code reaches production in this GitOps platform.

1

Repository Structure

The project is organized into clear directories:

k8s-gitops-lab/
# Application code
apps/guestbook/
  ├── Dockerfile
  ├── index.html
  ├── deployment.yaml
  ├── service.yaml
  └── ingress.yaml

# ArgoCD configuration
applications/
  └── guestbook.yaml

# One-time bootstrap
bootstrap/
  ├── project.yaml
  ├── app-of-apps.yaml
  └── cluster-issuer.yaml
Directory Purpose
apps/ Your application code and Kubernetes manifests
applications/ ArgoCD Application CRDs (what to deploy)
bootstrap/ One-time setup (applied manually)
.github/ CI pipeline (builds Docker images)
2

Bootstrap (One-Time Setup)

Run these 3 commands once to start the GitOps loop:

terminal
# 1. Create ArgoCD project (RBAC rules)
kubectl apply -f bootstrap/project.yaml

# 2. Create Let's Encrypt issuers (HTTPS)
kubectl apply -f bootstrap/cluster-issuer.yaml

# 3. Start GitOps loop (ArgoCD watches repo)
kubectl apply -f bootstrap/app-of-apps.yaml

# That's it! Everything else is automatic.
What Happens Next
1. ArgoCD reads applications/ directory
2. Finds guestbook.yaml
3. Reads apps/guestbook/ directory
4. Runs kustomize build
5. Deploys to cluster
3

Deploy Updates

When you want to update your app:

terminal
# 1. Edit your app
nano apps/guestbook/index.html

# 2. Commit and push (triggers CI)
git add apps/guestbook/
git commit -m "feat: update app"
git push

# 3. Wait for CI (2-3 min)
# 4. Update image tag
nano apps/guestbook/kustomization.yaml
# Change: newTag: <new-sha>

# 5. Commit and push (ArgoCD deploys)
git commit -m "deploy: update image"
git push
What Happens
1. GitHub Actions detects change in apps/guestbook/
2. Builds Docker image from Dockerfile
3. Pushes to GHCR with commit SHA tag
4. ArgoCD detects Git change in kustomization.yaml
5. Syncs new image to cluster
6. Pod restarts with new image
4

HTTPS & Security

Automatic HTTPS and security features:

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer:
      letsencrypt-production
spec:
  tls:
  - hosts:
    - guestbook.k8s.cmtmm.online
    secretName: guestbook-ui-tls
Security Features
Non-root container — Runs as UID 101 (nginx user)
Read-only filesystem — Cannot write to disk
Dropped capabilities — All Linux capabilities removed
Resource limits — CPU & memory boundaries
Health probes — Liveness & readiness checks
Auto-renewed TLS — Let's Encrypt via cert-manager
5

Self-Healing

ArgoCD continuously monitors the cluster:

self-healing
# Someone makes a manual change
kubectl edit deployment guestbook-ui

# ArgoCD detects the drift
⚠ Drift detected!

# ArgoCD reverts to match Git
✓ Reverted to Git state

# The cluster always matches Git.
Why This Matters
1. Consistency — Cluster always matches Git
2. Security — Manual changes are reverted
3. Audit trail — Every change is a Git commit
4. Rollbackgit revert undoes bad changes
5. Collaboration — Team reviews via Pull Requests
< updated -->