CI/CD Deployment Guide
Panduan Deployment dengan Gitea Runner
Dokumen ini menjelaskan langkah-langkah deployment otomatis untuk 3 microservices (users, products, orders) menggunakan CI/CD pipeline dengan Gitea Runner. Setiap tahap akan diukur waktunya untuk perbandingan dengan manual deployment.
Overview Deployment Process
Aplikasi yang Di-Deploy
| Service | Port | Fungsi | Container |
|---|---|---|---|
| users-service | 3001 | User management | Docker image |
| products-service | 3002 | Product catalog | Docker image |
| orders-service | 3003 | Order processing | Docker image |
Total Time Target
CI/CD deployment 3 services: <1 menit (60-90 detik)
Deployment Flow
Developer → Git Push (1 command)
↓
Gitea Webhook (instant trigger)
↓
Gitea Runner Pipeline Start (5-10 sec)
↓
CI Stage: Build & Push Images (30-40 sec)
↓
CD Stage: Deploy to K3s (20-30 sec)
↓
Health Check & Verification (5-10 sec)
↓
Deployment Complete ✅
Total: 60-90 seconds (ZERO manual intervention after git push)
Prerequisites
Sebelum deployment, pastikan sudah ada:
- ✅ K3s cluster running dan accessible
- ✅ Gitea server dengan repository aplikasi
- ✅ Gitea Runner configured dan connected
- ✅ Workflow file
.gitea/workflows/deploy.ymlsudah ada - ✅ Kubernetes deployment manifests di
/k8sfolder - ✅ Docker registry credentials configured
Step 1: Prepare Code Changes
⏱️ Estimated Time: Variable (developer coding time)
1.1 Make Code Changes
# Di local development machine
cd ~/projects/microservices-app
# Edit code di salah satu service
vim users-service/src/index.js
# Atau edit di semua services
vim products-service/src/controller.js
vim orders-service/src/routes.js
1.2 Test Locally (Optional)
# Test service locally
cd users-service
npm install
npm test
npm start
# Test di browser atau curl
curl http://localhost:3001/health
Time Checkpoint: ___ (development time, tidak dihitung dalam deployment)
Step 2: Commit Changes
⏱️ Estimated Time: 10-15 seconds
2.1 Stage Changes
# Add all changes
git add .
# Atau specific files
git add users-service/src/index.js
git add products-service/src/controller.js
git add orders-service/src/routes.js
2.2 Commit with Message
# Commit dengan message yang descriptive
git commit -m "feat: add new user validation logic"
# Atau
git commit -m "fix: resolve order calculation bug"
Output:
[main a1b2c3d] feat: add new user validation logic
3 files changed, 45 insertions(+), 12 deletions(-)
Time Checkpoint: ___ seconds
Step 3: Push to Gitea (Trigger Deployment)
⏱️ Estimated Time: 5-10 seconds
3.1 Push to Repository
# Push ke branch main (trigger CI/CD)
git push origin main
Output:
Enumerating objects: 15, done.
Counting objects: 100% (15/15), done.
Delta compression using up to 8 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (9/9), 2.43 KiB | 2.43 MiB/s, done.
Total 9 (delta 5), reused 0 (delta 0), pack-reused 0
To https://gitea.example.com/yourname/microservices-app.git
e4f5g6h..a1b2c3d main -> main
3.2 Webhook Triggered Automatically
Gitea otomatis trigger webhook ke Gitea Runner.
🎉 DEPLOYMENT DIMULAI OTOMATIS! 🎉
Time Checkpoint: ___ seconds
Step 4: Monitor CI/CD Pipeline
⏱️ Estimated Time: 60-90 seconds (automated)
4.1 Check Pipeline Status di Gitea UI
Buka browser:
https://gitea.example.com/yourname/microservices-app/actions
Atau via CLI:
# List recent workflow runs
gitea actions list
# Watch specific run
gitea actions view <run-id> --watch
4.2 Pipeline Stages
Pipeline akan menjalankan stages berikut secara otomatis:
Stage 1: Checkout Code (5 sec)
- name: Checkout code
uses: actions/checkout@v3
✅ Runner clone repository
Stage 2: Build Docker Images (30-40 sec)
- name: Build users-service
run: |
docker build -t gitea.example.com/yourname/users-service:${{ github.sha }} ./users-service
- name: Build products-service
run: |
docker build -t gitea.example.com/yourname/products-service:${{ github.sha }} ./products-service
- name: Build orders-service
run: |
docker build -t gitea.example.com/yourname/orders-service:${{ github.sha }} ./orders-service
✅ Build 3 Docker images (parallel)
Stage 3: Push to Registry (10-15 sec)
- name: Push images to registry
run: |
docker push gitea.example.com/yourname/users-service:${{ github.sha }}
docker push gitea.example.com/yourname/products-service:${{ github.sha }}
docker push gitea.example.com/yourname/orders-service:${{ github.sha }}
✅ Upload images ke Gitea container registry
Stage 4: Deploy to K3s (20-30 sec)
- name: Update K3s deployments
run: |
kubectl set image deployment/users-service \
users-service=gitea.example.com/yourname/users-service:${{ github.sha }}
kubectl set image deployment/products-service \
products-service=gitea.example.com/yourname/products-service:${{ github.sha }}
kubectl set image deployment/orders-service \
orders-service=gitea.example.com/yourname/orders-service:${{ github.sha }}
✅ Update deployments dengan rolling update (ZERO DOWNTIME)
Stage 5: Wait for Rollout (10-15 sec)
- name: Wait for deployments
run: |
kubectl rollout status deployment/users-service --timeout=60s
kubectl rollout status deployment/products-service --timeout=60s
kubectl rollout status deployment/orders-service --timeout=60s
✅ Tunggu semua pods ready
Stage 6: Health Check (5 sec)
- name: Health check
run: |
curl -f http://users-service:3001/health
curl -f http://products-service:3002/health
curl -f http://orders-service:3003/health
✅ Verify services responding
Time Checkpoint for entire pipeline: ___ seconds
Step 5: Verify Deployment Success
⏱️ Estimated Time: 10-20 seconds (manual verification)
5.1 Check Pipeline Status
Di Gitea UI, pastikan semua stages ✅ success:
✅ Checkout code (5s)
✅ Build images (35s)
✅ Push to registry (12s)
✅ Deploy to K3s (25s)
✅ Wait for rollout (12s)
✅ Health check (5s)
━━━━━━━━━━━━━━━━━━━━━━━━━
Total: 94 seconds
5.2 Check K3s Deployments
# Check all deployments
kubectl get deployments
# Check pods
kubectl get pods
# Check services
kubectl get svc
Expected Output:
NAME READY UP-TO-DATE AVAILABLE AGE
users-service 3/3 3 3 2m
products-service 3/3 3 3 2m
orders-service 3/3 3 3 2m
5.3 Test Services
# Test each service health
kubectl port-forward svc/users-service 3001:3001 &
curl http://localhost:3001/health
kubectl port-forward svc/products-service 3002:3002 &
curl http://localhost:3002/health
kubectl port-forward svc/orders-service 3003:3003 &
curl http://localhost:3003/health
Expected Response:
{
"status": "ok",
"service": "users-service",
"version": "a1b2c3d",
"timestamp": "2024-01-15T10:35:22.123Z"
}
Time Checkpoint for verification: ___ seconds
Total Deployment Time Summary
| Step | Estimated Time | Actual Time | Manual? |
|---|---|---|---|
| 1. Code changes | Variable | N/A | ✅ Yes |
| 2. Git commit | 10-15 sec | ___ sec | ✅ Yes |
| 3. Git push | 5-10 sec | ___ sec | ✅ Yes |
| 4. CI/CD Pipeline | 60-90 sec | ___ sec | ❌ Automated |
| 5. Verification | 10-20 sec | ___ sec | ✅ Yes (optional) |
| DEPLOYMENT TOTAL | 60-90 sec | ___ sec | Mostly Automated |
Total Downtime: 0 seconds (rolling update)
Metrics Collected
Manual Intervention Count
Total manual commands yang harus dijalankan:
git add .- 1 commandgit commit -m "message"- 1 commandgit push origin main- 1 command- Verification (optional) - 3 commands
Total: 3 mandatory commands (vs 17-21 pada manual deployment)
Actual deployment commands: 1 (git push only, sisanya otomatis)
Human Error Points
Potential errors yang bisa terjadi:
- ❌ Lupa commit changes (prevented by Git)
- ❌ Push ke branch yang salah (Git protection rules)
- ⚠️ Build failure (automatic rollback)
- ⚠️ Health check failure (automatic rollback)
Error Probability: <1% (automated & consistent)
Automation Benefits
- ✅ No manual SSH required
- ✅ No manual npm install
- ✅ No manual service restart
- ✅ Automatic image versioning
- ✅ Automatic rollback on failure
- ✅ Zero downtime deployment
- ✅ Consistent every time
Rollout Strategy
Rolling Update (Default)
K3s menggunakan rolling update strategy:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 1 pod extra during update
maxUnavailable: 0 # Always keep minimum pods running
Process:
Old Pods: [V1] [V1] [V1]
↓
Step 1: [V1] [V1] [V1] [V2] ← Start 1 new pod
Step 2: [V1] [V1] [V2] ← Kill 1 old pod
Step 3: [V1] [V1] [V2] [V2] ← Start another
Step 4: [V1] [V2] [V2] ← Kill old
Step 5: [V1] [V2] [V2] [V2] ← Start last
Step 6: [V2] [V2] [V2] ← Kill final old pod
Result: Zero downtime! Always have running pods.
Health Checks
Kubernetes health checks ensure safe rollout:
livenessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 3001
initialDelaySeconds: 5
periodSeconds: 3
- Liveness: Restart pod if unhealthy
- Readiness: Don't send traffic until ready
Rollback Procedure
Automatic Rollback
Jika deployment gagal (health check fails), K3s otomatis rollback:
- name: Deploy with rollback
run: |
kubectl set image deployment/users-service users-service=new-image:tag
kubectl rollout status deployment/users-service --timeout=60s || \
kubectl rollout undo deployment/users-service
Manual Rollback
Jika perlu rollback manual:
# Check rollout history
kubectl rollout history deployment/users-service
# Rollback to previous version
kubectl rollout undo deployment/users-service
# Rollback to specific revision
kubectl rollout undo deployment/users-service --to-revision=2
# Verify rollback
kubectl rollout status deployment/users-service
Rollback Time: 10-20 seconds (automated)
Troubleshooting
Issue 1: Pipeline Failed at Build Stage
Error:
Error: failed to build image: exit status 1
Check Logs:
# Di Gitea UI, klik pada failed stage untuk lihat logs
# Atau via CLI
gitea actions logs <run-id> <job-id>
Common Causes:
- Dockerfile syntax error
- Missing dependencies in package.json
- Build context issues
Solution:
# Fix the issue locally first
cd users-service
docker build -t test .
# If successful, commit and push again
git add .
git commit -m "fix: resolve build issue"
git push origin main
Issue 2: Deployment Timeout
Error:
Error: timed out waiting for deployment rollout
Check Pods:
# Check pod status
kubectl get pods
# Check pod logs
kubectl logs deployment/users-service
# Describe pod for events
kubectl describe pod <pod-name>
Common Causes:
- Image pull failure
- Health check failing
- Resource limits exceeded
Solution:
# Check events
kubectl get events --sort-by='.lastTimestamp'
# Fix issue and redeploy
git commit -m "fix: adjust resource limits"
git push origin main
Issue 3: Health Check Failed
Error:
Health check failed: curl: (7) Failed to connect
Debug:
# Port-forward to pod
kubectl port-forward deployment/users-service 3001:3001
# Test locally
curl http://localhost:3001/health
# Check service logs
kubectl logs deployment/users-service --tail=100
Solution:
- Ensure health endpoint is implemented
- Check port configuration
- Verify service is starting correctly
Monitoring Deployment
Real-time Monitoring
# Watch deployments
watch kubectl get deployments
# Watch pods
watch kubectl get pods
# Stream logs
kubectl logs -f deployment/users-service
# Monitor events
kubectl get events --watch
Gitea Actions Dashboard
Monitor di browser:
https://gitea.example.com/yourname/microservices-app/actions/runs/<run-id>
Features:
- ✅ Real-time logs
- ✅ Stage duration
- ✅ Artifact download
- ✅ Re-run failed jobs
- ✅ Cancel running jobs
Best Practices
✅ Pre-Deployment
- Test locally before pushing
- Write meaningful commit messages
- Review changes before push
- Ensure tests pass locally
- Check CI/CD pipeline status
✅ During Deployment
- Monitor pipeline progress
- Check logs for errors
- Verify rollout status
- Don't force-push during deployment
- Keep Git history clean
✅ Post-Deployment
- Verify all services healthy
- Monitor error rates
- Check application metrics
- Review deployment logs
- Tag release versions
Deployment Log
Pipeline automatically logs deployment:
- name: Log deployment
run: |
echo "Deployed by: ${{ github.actor }}"
echo "Commit: ${{ github.sha }}"
echo "Branch: ${{ github.ref }}"
echo "Time: $(date)"
View logs:
# Via Gitea UI
https://gitea.example.com/yourname/microservices-app/actions
# Via kubectl
kubectl logs deployment/users-service | grep "Started"
Comparison with Manual Deployment
| Metric | Manual Deployment | CI/CD Deployment |
|---|---|---|
| Trigger | SSH + 17-21 commands | 1 git push |
| Total Time | 3-5 minutes | 60-90 seconds |
| Downtime | 30-60 seconds | 0 seconds |
| Manual Steps | 17-21 | 3 (git workflow) |
| Consistency | Low (human variance) | High (automated) |
| Error Prone | High (5-10%) | Low (<1%) |
| Rollback | Manual (3-5 min) | Automatic (10-20 sec) |
| Audit Trail | Manual logs | Git history + pipeline logs |
| Scalability | Limited (manual) | Unlimited (automated) |
Improvement:
- ⏱️ 70-80% faster
- 👤 94% less manual work (3 vs 21 commands)
- ⏰ 100% downtime elimination
- ✅ Significantly more reliable
Workflow File Example
Sample .gitea/workflows/deploy.yml:
name: CI/CD Pipeline
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build Docker images
run: |
docker build -t gitea.example.com/app/users-service:${{ github.sha }} ./users-service
docker build -t gitea.example.com/app/products-service:${{ github.sha }} ./products-service
docker build -t gitea.example.com/app/orders-service:${{ github.sha }} ./orders-service
- name: Push to registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login gitea.example.com -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin
docker push gitea.example.com/app/users-service:${{ github.sha }}
docker push gitea.example.com/app/products-service:${{ github.sha }}
docker push gitea.example.com/app/orders-service:${{ github.sha }}
- name: Deploy to K3s
run: |
kubectl set image deployment/users-service users-service=gitea.example.com/app/users-service:${{ github.sha }}
kubectl set image deployment/products-service products-service=gitea.example.com/app/products-service:${{ github.sha }}
kubectl set image deployment/orders-service orders-service=gitea.example.com/app/orders-service:${{ github.sha }}
kubectl rollout status deployment/users-service --timeout=60s
kubectl rollout status deployment/products-service --timeout=60s
kubectl rollout status deployment/orders-service --timeout=60s
Conclusion
CI/CD deployment untuk 3 microservices menghasilkan:
- ⏱️ Time: 60-90 detik (dari git push sampai deployed)
- 👤 Manual effort: 3 commands (git add, commit, push)
- 🤖 Automation: 100% setelah git push
- ⏰ Downtime: 0 detik (rolling update)
- ❌ Risk: <1% (automated & konsisten)
- 🔄 Rollback: Automatic dalam 10-20 detik
Hasil pengujian aktual akan didokumentasikan di Test Results untuk dibandingkan dengan manual deployment.
Next Steps
Setelah memahami CI/CD deployment, lihat hasil perbandingan:
👉 Manual Deployment - Bandingkan dengan cara manual
👉 Test Results - Hasil pengujian lengkap
👉 Operational Comparison - Perbandingan operasional detail