This commit is contained in:
271
DEPLOY.md
271
DEPLOY.md
@@ -14,6 +14,8 @@
|
||||
6. [Troubleshooting Guide](#6-troubleshooting-guide)
|
||||
7. [Updating the Application](#7-updating-the-application)
|
||||
8. [Teardown](#8-teardown)
|
||||
9. [CI/CD — Jenkins Multibranch Pipeline](#9-cicd--jenkins-multibranch-pipeline)
|
||||
10. [GitOps — ArgoCD (Reference)](#10-gitops--argocd-reference)
|
||||
|
||||
---
|
||||
|
||||
@@ -797,6 +799,275 @@ kubectl delete -f https://raw.githubusercontent.com/rancher/local-path-provision
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 9. CI/CD — Jenkins Multibranch Pipeline
|
||||
|
||||
This project ships with a `Jenkinsfile` at the repo root that automates the full
|
||||
build → test → push → deploy lifecycle.
|
||||
|
||||
### 9.1 Prerequisites on the Jenkins Server
|
||||
|
||||
| Tool | Purpose | Install |
|
||||
|------|---------|---------|
|
||||
| Docker | Build & push images | `apt install docker.io` + add `jenkins` user to `docker` group |
|
||||
| kubectl | Apply k8s manifests | [Official install guide](https://kubernetes.io/docs/tasks/tools/) |
|
||||
| kustomize | Render overlays | `curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash` |
|
||||
| NodeJS (v18+) | `npm ci` / `npm test` | Jenkins NodeJS plugin or system package |
|
||||
|
||||
```bash
|
||||
# Add jenkins user to docker group (run on Jenkins host, then restart Jenkins)
|
||||
sudo usermod -aG docker jenkins
|
||||
sudo systemctl restart jenkins
|
||||
```
|
||||
|
||||
### 9.2 Jenkins Plugins Required
|
||||
|
||||
Install via **Manage Jenkins → Plugins**:
|
||||
|
||||
| Plugin | Purpose |
|
||||
|--------|---------|
|
||||
| **Multibranch Pipeline** | Detects branches + PRs automatically |
|
||||
| **Docker Pipeline** | Docker credential binding |
|
||||
| **Credentials Binding** | Injects secrets into pipeline steps |
|
||||
| **NodeJS** | Managed Node.js installations |
|
||||
| **Git** | SCM checkout |
|
||||
|
||||
### 9.3 Configure Jenkins Credentials
|
||||
|
||||
Go to **Manage Jenkins → Credentials → System → Global credentials → Add**:
|
||||
|
||||
| Credential ID | Kind | Fields | Used for |
|
||||
|---------------|------|--------|---------|
|
||||
| `dockerhub-credentials` | Username with password | Username: `subkamble` / Password: Docker Hub PAT | `docker push` |
|
||||
| `kubeconfig-secret` | Secret file | Upload your `~/.kube/config` | `kubectl` cluster access |
|
||||
|
||||
> **Docker Hub PAT:** Generate at hub.docker.com → Account Settings → Security → New Access Token (Read/Write scope).
|
||||
|
||||
> **kubeconfig tip:** If Jenkins runs inside the same cluster, use a ServiceAccount + RBAC instead of a kubeconfig file.
|
||||
|
||||
### 9.4 Create the Multibranch Pipeline Job
|
||||
|
||||
1. **Jenkins Dashboard → New Item**
|
||||
2. Name: `react-mysql` → select **Multibranch Pipeline** → OK
|
||||
3. Under **Branch Sources** → Add source → **Git**
|
||||
- Repository URL: your repo URL
|
||||
- Credentials: add repo access if private
|
||||
4. Under **Build Configuration** → Mode: **by Jenkinsfile** → Script Path: `Jenkinsfile`
|
||||
5. Under **Scan Multibranch Pipeline Triggers** → enable **Periodically if not otherwise run** (e.g. every 5 min), or configure a webhook (preferred)
|
||||
6. Save → **Scan Multibranch Pipeline Now**
|
||||
|
||||
Jenkins will discover all branches and create sub-jobs automatically.
|
||||
|
||||
### 9.5 Webhook Setup (recommended — avoids polling)
|
||||
|
||||
**GitHub:**
|
||||
1. Repo → Settings → Webhooks → Add webhook
|
||||
2. Payload URL: `http://<JENKINS_URL>/multibranch-webhook-trigger/invoke?token=react-mysql`
|
||||
3. Content type: `application/json`
|
||||
4. Events: **Push** + **Pull requests**
|
||||
|
||||
Install the **Multibranch Scan Webhook Trigger** plugin on Jenkins to handle the token.
|
||||
|
||||
### 9.6 Branch Behavior Summary
|
||||
|
||||
| Branch | Build | Test | Push Image | Deploy |
|
||||
|--------|-------|------|-----------|--------|
|
||||
| `main` | Yes | Yes | Yes (`latest` + SHA tag) | `k8s/overlays/onpremise` (production) |
|
||||
| `staging` | Yes | Yes | Yes (branch-SHA tag) | `k8s/overlays/minikube` (staging) |
|
||||
| `develop` | Yes | Yes | No | No |
|
||||
| `feature/**` | Yes | Yes | No | No |
|
||||
| PR branches | Yes | Yes | No | No |
|
||||
|
||||
### 9.7 Image Tagging Convention
|
||||
|
||||
| Branch | Tag format | Example |
|
||||
|--------|-----------|---------|
|
||||
| `main` | `latest` + `<sha8>` | `latest`, `a1b2c3d4` |
|
||||
| `staging` | `staging-<sha8>` | `staging-a1b2c3d4` |
|
||||
| `feature/login` | `feature-login-<sha8>` | `feature-login-a1b2c3d4` |
|
||||
|
||||
### 9.8 First-Run Checklist
|
||||
|
||||
```bash
|
||||
# Verify Jenkins can reach Docker Hub
|
||||
docker login -u subkamble
|
||||
|
||||
# Verify Jenkins can reach the cluster
|
||||
kubectl get nodes
|
||||
|
||||
# Verify kustomize is on PATH
|
||||
kustomize version
|
||||
|
||||
# Trigger a manual build for main branch from Jenkins UI
|
||||
# then watch the Console Output for each stage
|
||||
```
|
||||
|
||||
### 9.9 Rollback
|
||||
|
||||
```bash
|
||||
# List available image tags (via Docker Hub API or local docker images)
|
||||
docker images subkamble/react-mysql-backend
|
||||
|
||||
# Pin a specific tag manually and re-deploy
|
||||
cd k8s/base
|
||||
kustomize edit set image \
|
||||
subkamble/react-mysql-backend=subkamble/react-mysql-backend:<previous-sha> \
|
||||
subkamble/react-mysql-frontend=subkamble/react-mysql-frontend:<previous-sha>
|
||||
cd -
|
||||
kubectl apply -k k8s/overlays/onpremise
|
||||
kubectl rollout status deployment/backend -n react-mysql
|
||||
kubectl rollout status deployment/frontend -n react-mysql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. GitOps — ArgoCD (Reference)
|
||||
|
||||
> The Jenkinsfile contains fully commented-out ArgoCD pipeline stages.
|
||||
> Follow this section to activate GitOps mode.
|
||||
|
||||
### 10.1 Install ArgoCD
|
||||
|
||||
```bash
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd \
|
||||
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
|
||||
# Wait for all ArgoCD pods to be ready
|
||||
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=180s
|
||||
|
||||
# Expose the ArgoCD API server (choose one):
|
||||
|
||||
# Option A — Port-forward (local access only)
|
||||
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
||||
|
||||
# Option B — LoadBalancer (on-prem with MetalLB or cloud)
|
||||
kubectl patch svc argocd-server -n argocd \
|
||||
-p '{"spec":{"type":"LoadBalancer"}}'
|
||||
|
||||
# Option C — Ingress (add argocd.myapp.local to your Ingress controller)
|
||||
```
|
||||
|
||||
### 10.2 Get Initial Admin Password
|
||||
|
||||
```bash
|
||||
kubectl get secret argocd-initial-admin-secret \
|
||||
-n argocd \
|
||||
-o jsonpath="{.data.password}" | base64 -d && echo
|
||||
|
||||
# Login
|
||||
argocd login localhost:8080 --username admin --password <above-password> --insecure
|
||||
|
||||
# Change password immediately
|
||||
argocd account update-password
|
||||
```
|
||||
|
||||
### 10.3 Apply ArgoCD Application Manifests
|
||||
|
||||
Create the two Application objects (one per environment).
|
||||
These are documented in full inside the `Jenkinsfile` comments.
|
||||
Here is the summary of what they do:
|
||||
|
||||
| Application | Watches branch | Overlay | Sync policy |
|
||||
|-------------|---------------|---------|------------|
|
||||
| `react-mysql-production` | `main` | `k8s/overlays/onpremise` | Automated (prune + selfHeal) |
|
||||
| `react-mysql-staging` | `staging` | `k8s/overlays/minikube` | Automated (prune + selfHeal) |
|
||||
|
||||
```bash
|
||||
# Copy the YAML blocks from the Jenkinsfile comments into files, then:
|
||||
kubectl apply -f argocd/application-production.yaml
|
||||
kubectl apply -f argocd/application-staging.yaml
|
||||
|
||||
# Verify apps are registered
|
||||
argocd app list
|
||||
```
|
||||
|
||||
### 10.4 Jenkins Credentials for GitOps Mode
|
||||
|
||||
Add these alongside the existing credentials:
|
||||
|
||||
| Credential ID | Kind | Purpose |
|
||||
|---------------|------|---------|
|
||||
| `argocd-auth-token` | Secret text | ArgoCD API token for `argocd app sync` |
|
||||
| `gitops-ssh-key` | SSH username with private key | Push image tag updates back to Git |
|
||||
|
||||
**Generate an ArgoCD API token:**
|
||||
```bash
|
||||
argocd account generate-token --account admin
|
||||
# Copy the output → paste as the 'argocd-auth-token' secret text
|
||||
```
|
||||
|
||||
### 10.5 Activate GitOps in the Jenkinsfile
|
||||
|
||||
1. Open `Jenkinsfile`
|
||||
2. Remove the active **Deploy** and **Smoke Test** stages (or leave them as fallback)
|
||||
3. Uncomment the `Update GitOps Manifest` and `ArgoCD Sync` stage blocks in the GitOps section at the bottom
|
||||
4. Replace `YOUR_ARGOCD_SERVER` with your ArgoCD server hostname/IP
|
||||
5. Replace `YOUR_ORG` in the git clone URL with your GitHub org/username
|
||||
6. Commit and push — Jenkins picks up the change automatically
|
||||
|
||||
### 10.6 GitOps Flow Diagram
|
||||
|
||||
```
|
||||
Developer pushes code
|
||||
│
|
||||
▼
|
||||
Jenkins CI
|
||||
┌─────────────────────────────────────┐
|
||||
│ 1. npm ci → test │
|
||||
│ 2. docker build + push :<sha-tag> │
|
||||
│ 3. kustomize edit set image │
|
||||
│ 4. git commit + push [skip ci] │
|
||||
└─────────────────┬───────────────────┘
|
||||
│ Git push (image tag bump)
|
||||
▼
|
||||
Git Repository
|
||||
(k8s/base/kustomization.yaml updated)
|
||||
│
|
||||
│ ArgoCD polls every 3 min
|
||||
│ (or Jenkins triggers sync via argocd CLI)
|
||||
▼
|
||||
ArgoCD detects drift
|
||||
┌────────────────────────────┐
|
||||
│ kubectl apply -k overlay/ │
|
||||
│ prune removed resources │
|
||||
│ self-heal manual changes │
|
||||
└────────────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
Kubernetes Cluster
|
||||
(react-mysql namespace updated)
|
||||
```
|
||||
|
||||
### 10.7 ArgoCD Quick Reference
|
||||
|
||||
```bash
|
||||
# View app status
|
||||
argocd app get react-mysql-production
|
||||
|
||||
# Force immediate sync (skip waiting for poll interval)
|
||||
argocd app sync react-mysql-production
|
||||
|
||||
# Rollback to previous revision
|
||||
argocd app history react-mysql-production
|
||||
argocd app rollback react-mysql-production <revision-id>
|
||||
|
||||
# Pause auto-sync (for maintenance)
|
||||
argocd app set react-mysql-production --sync-policy none
|
||||
|
||||
# Resume auto-sync
|
||||
argocd app set react-mysql-production --sync-policy automated
|
||||
|
||||
# Delete app (does NOT delete k8s resources by default)
|
||||
argocd app delete react-mysql-production
|
||||
|
||||
# Delete app AND k8s resources
|
||||
argocd app delete react-mysql-production --cascade
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Card
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user