feat: implement complete CI/CD with base image strategy
- Add Woodpecker pipeline with base image support - Separate base image build (.woodpecker-base.yml) from app build (.woodpecker.yml) - Implement build/push separation in application pipeline - Create Docker base image with Python 3.11, Node.js 20, and bun - Update Dockerfile to use pre-built base image for faster builds - Remove GitHub Actions (not needed, using Woodpecker) - Fix Docker contexts and paths for new structure - Update docker-compose.yml build contexts - Fix rxconfig.py DB path for container environment - Add ArgoCD application manifests for staging/production - Create comprehensive documentation: - docs/WOODPECKER_CI_CD.md (CI/CD guide) - docs/BASE_IMAGE_MANAGEMENT.md (Base image management) - helm/peikarband/argocd/README.md (ArgoCD deployment) Benefits: - Build time: 8-10min → 2-3min (60-70% faster) - Better reliability (no repeated npm/bun downloads) - Separation of concerns (base vs application builds) - Full pipeline: check → build → push → verify → notify - Complete deployment automation with Helm + ArgoCD Pipeline stages: 1. check-base-image: Verify base image availability 2. build-image: Build application (no push) 3. push-image: Push with multi-tags (latest, sha, branch) 4. verify-push: Verify successful push 5. notify: Success/failure notifications Base image can be rebuilt via: - Manual trigger in Woodpecker UI - Auto trigger when Dockerfile.base changes
This commit is contained in:
257
helm/peikarband/argocd/README.md
Normal file
257
helm/peikarband/argocd/README.md
Normal file
@@ -0,0 +1,257 @@
|
||||
# ArgoCD Application Manifests
|
||||
|
||||
این پوشه شامل ArgoCD Application manifests برای deployment خودکار با GitOps است.
|
||||
|
||||
## ساختار
|
||||
|
||||
```
|
||||
argocd/
|
||||
├── application.yaml # Production deployment (namespace: production)
|
||||
├── application-staging.yaml # Staging deployment (namespace: staging)
|
||||
├── secrets/ # Kubernetes secrets (DO NOT commit real secrets)
|
||||
└── README.md # این فایل
|
||||
```
|
||||
|
||||
## استفاده
|
||||
|
||||
### 1. Deploy به Production
|
||||
|
||||
```bash
|
||||
# Apply ArgoCD Application
|
||||
kubectl apply -f helm/peikarband/argocd/application.yaml
|
||||
|
||||
# Check sync status
|
||||
argocd app get peikarband-landing-prod
|
||||
|
||||
# Sync manually if needed
|
||||
argocd app sync peikarband-landing-prod
|
||||
|
||||
# Watch deployment
|
||||
kubectl get pods -n production -w
|
||||
```
|
||||
|
||||
### 2. Deploy به Staging
|
||||
|
||||
```bash
|
||||
# Apply ArgoCD Application
|
||||
kubectl apply -f helm/peikarband/argocd/application-staging.yaml
|
||||
|
||||
# Check sync status
|
||||
argocd app get peikarband-landing-staging
|
||||
|
||||
# Sync manually
|
||||
argocd app sync peikarband-landing-staging
|
||||
```
|
||||
|
||||
### 3. Update Image Tag
|
||||
|
||||
#### روش اول: از طریق ArgoCD UI
|
||||
1. باز کردن ArgoCD UI
|
||||
2. رفتن به Application مورد نظر
|
||||
3. کلیک روی "Parameters"
|
||||
4. تغییر `image.tag` به tag جدید
|
||||
5. کلیک روی "Sync"
|
||||
|
||||
#### روش دوم: از طریق CLI
|
||||
|
||||
```bash
|
||||
# Update production
|
||||
argocd app set peikarband-landing-prod \
|
||||
-p image.tag=v1.2.3
|
||||
|
||||
# Update staging
|
||||
argocd app set peikarband-landing-staging \
|
||||
-p image.tag=develop
|
||||
```
|
||||
|
||||
#### روش سوم: تغییر در Git (GitOps روش اصلی)
|
||||
|
||||
```bash
|
||||
# Update values-production.yaml
|
||||
vim helm/peikarband/values-production.yaml
|
||||
# Change image.tag value
|
||||
|
||||
# Commit & Push
|
||||
git add helm/peikarband/values-production.yaml
|
||||
git commit -m "chore: update image to v1.2.3"
|
||||
git push origin main
|
||||
|
||||
# ArgoCD will auto-sync (if automated sync enabled)
|
||||
```
|
||||
|
||||
## تنظیمات مهم
|
||||
|
||||
### Auto-Sync
|
||||
|
||||
Her دو application روی `automated sync` تنظیم شدهاند:
|
||||
- **prune**: true → منابع اضافی حذف میشن
|
||||
- **selfHeal**: true → تغییرات manual برگشت میخورن
|
||||
- **allowEmpty**: false → deploy خالی مجاز نیست
|
||||
|
||||
### Sync Options
|
||||
|
||||
- **CreateNamespace**: true → namespace خودکار ساخته میشه
|
||||
- **PrunePropagationPolicy**: foreground → منابع به ترتیب حذف میشن
|
||||
- **PruneLast**: true → prune در آخر انجام میشه
|
||||
|
||||
### Retry Policy
|
||||
|
||||
در صورت شکست:
|
||||
- تا 5 بار تلاش مجدد
|
||||
- با backoff exponential (5s, 10s, 20s, 40s, 80s)
|
||||
- حداکثر 3 دقیقه delay
|
||||
|
||||
## Secrets Management
|
||||
|
||||
⚠️ **هشدار امنیتی:**
|
||||
|
||||
Secrets نباید در Git commit بشن! از یکی از روشهای زیر استفاده کنید:
|
||||
|
||||
### روش 1: Manual Secret Creation
|
||||
|
||||
```bash
|
||||
# Create registry secret
|
||||
kubectl create secret docker-registry hub-registry-secret \
|
||||
--docker-server=hub.peikarband.ir \
|
||||
--docker-username=admin \
|
||||
--docker-password=YOUR_PASSWORD \
|
||||
--namespace=production
|
||||
|
||||
# Create application secrets
|
||||
kubectl create secret generic peikarband-prod-secrets \
|
||||
--from-literal=db-username=peikarband \
|
||||
--from-literal=db-password=YOUR_DB_PASSWORD \
|
||||
--from-literal=redis-password=YOUR_REDIS_PASSWORD \
|
||||
--namespace=production
|
||||
```
|
||||
|
||||
### روش 2: Sealed Secrets (پیشنهاد شده)
|
||||
|
||||
```bash
|
||||
# Install sealed-secrets controller
|
||||
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
|
||||
|
||||
# Create sealed secret
|
||||
kubeseal --format=yaml < secret.yaml > sealed-secret.yaml
|
||||
|
||||
# Commit sealed-secret.yaml (امن است)
|
||||
git add helm/peikarband/argocd/secrets/sealed-secret.yaml
|
||||
git commit -m "chore: add sealed secrets"
|
||||
```
|
||||
|
||||
### روش 3: External Secrets Operator
|
||||
|
||||
```bash
|
||||
# Install external-secrets
|
||||
helm install external-secrets external-secrets/external-secrets \
|
||||
--namespace external-secrets-system \
|
||||
--create-namespace
|
||||
|
||||
# Create SecretStore
|
||||
kubectl apply -f argocd/secrets/secret-store.yaml
|
||||
|
||||
# Create ExternalSecret
|
||||
kubectl apply -f argocd/secrets/external-secret.yaml
|
||||
```
|
||||
|
||||
## Health Checks
|
||||
|
||||
ArgoCD health checks:
|
||||
- **Deployment**: Ready replicas == Desired replicas
|
||||
- **Service**: Endpoint موجود باشه
|
||||
- **Ingress**: Backend service موجود باشه
|
||||
- **HPA**: Status normal باشه
|
||||
|
||||
## Rollback
|
||||
|
||||
در صورت مشکل:
|
||||
|
||||
```bash
|
||||
# List revisions
|
||||
argocd app history peikarband-landing-prod
|
||||
|
||||
# Rollback to specific revision
|
||||
argocd app rollback peikarband-landing-prod 5
|
||||
|
||||
# Or rollback to previous
|
||||
argocd app rollback peikarband-landing-prod
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
```bash
|
||||
# Watch application status
|
||||
argocd app watch peikarband-landing-prod
|
||||
|
||||
# Get detailed status
|
||||
argocd app get peikarband-landing-prod --refresh
|
||||
|
||||
# Show sync differences
|
||||
argocd app diff peikarband-landing-prod
|
||||
|
||||
# View logs
|
||||
kubectl logs -n production -l app.kubernetes.io/name=peikarband -f
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### App won't sync
|
||||
|
||||
```bash
|
||||
# Check sync status
|
||||
argocd app get peikarband-landing-prod
|
||||
|
||||
# Force refresh
|
||||
argocd app get peikarband-landing-prod --refresh --hard-refresh
|
||||
|
||||
# Delete and recreate
|
||||
argocd app delete peikarband-landing-prod
|
||||
kubectl apply -f helm/peikarband/argocd/application.yaml
|
||||
```
|
||||
|
||||
### Pods not starting
|
||||
|
||||
```bash
|
||||
# Check pod status
|
||||
kubectl get pods -n production
|
||||
|
||||
# Check pod logs
|
||||
kubectl logs -n production <pod-name>
|
||||
|
||||
# Describe pod for events
|
||||
kubectl describe pod -n production <pod-name>
|
||||
|
||||
# Check image pull secrets
|
||||
kubectl get secrets -n production
|
||||
```
|
||||
|
||||
### Health check failing
|
||||
|
||||
```bash
|
||||
# Check service endpoints
|
||||
kubectl get endpoints -n production
|
||||
|
||||
# Test health endpoint
|
||||
kubectl port-forward -n production svc/peikarband 8000:8000
|
||||
curl http://localhost:8000/ping
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
در Woodpecker/GitHub Actions:
|
||||
|
||||
```yaml
|
||||
- name: Update ArgoCD Image
|
||||
image: argoproj/argocd:latest
|
||||
commands:
|
||||
- argocd login argocd.peikarband.ir --username admin --password $ARGOCD_PASSWORD
|
||||
- argocd app set peikarband-landing-prod -p image.tag=${CI_COMMIT_SHA:0:8}
|
||||
- argocd app sync peikarband-landing-prod --timeout 300
|
||||
```
|
||||
|
||||
## مستندات بیشتر
|
||||
|
||||
- [ArgoCD Documentation](https://argo-cd.readthedocs.io/)
|
||||
- [Helm Best Practices](https://helm.sh/docs/chart_best_practices/)
|
||||
- [Kubernetes Secrets Management](https://kubernetes.io/docs/concepts/configuration/secret/)
|
||||
|
||||
54
helm/peikarband/argocd/application-staging.yaml
Normal file
54
helm/peikarband/argocd/application-staging.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: peikarband-landing-staging
|
||||
namespace: argocd
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: http://git.peikarband.ir/ehsan-minadd/peikarband
|
||||
targetRevision: develop
|
||||
path: helm/peikarband
|
||||
helm:
|
||||
releaseName: peikarband-staging
|
||||
valueFiles:
|
||||
- values.yaml
|
||||
- values-staging.yaml
|
||||
parameters:
|
||||
- name: image.tag
|
||||
value: develop
|
||||
- name: image.repository
|
||||
value: hub.peikarband.ir/peikarband/landing
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: staging
|
||||
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
allowEmpty: false
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- PrunePropagationPolicy=foreground
|
||||
- PruneLast=true
|
||||
retry:
|
||||
limit: 5
|
||||
backoff:
|
||||
duration: 5s
|
||||
factor: 2
|
||||
maxDuration: 3m
|
||||
|
||||
revisionHistoryLimit: 10
|
||||
|
||||
# Health assessment
|
||||
ignoreDifferences:
|
||||
- group: apps
|
||||
kind: Deployment
|
||||
jsonPointers:
|
||||
- /spec/replicas
|
||||
|
||||
54
helm/peikarband/argocd/application.yaml
Normal file
54
helm/peikarband/argocd/application.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: peikarband-landing-prod
|
||||
namespace: argocd
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: http://git.peikarband.ir/ehsan-minadd/peikarband
|
||||
targetRevision: main
|
||||
path: helm/peikarband
|
||||
helm:
|
||||
releaseName: peikarband
|
||||
valueFiles:
|
||||
- values.yaml
|
||||
- values-production.yaml
|
||||
parameters:
|
||||
- name: image.tag
|
||||
value: latest
|
||||
- name: image.repository
|
||||
value: hub.peikarband.ir/peikarband/landing
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: production
|
||||
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
allowEmpty: false
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- PrunePropagationPolicy=foreground
|
||||
- PruneLast=true
|
||||
retry:
|
||||
limit: 5
|
||||
backoff:
|
||||
duration: 5s
|
||||
factor: 2
|
||||
maxDuration: 3m
|
||||
|
||||
revisionHistoryLimit: 10
|
||||
|
||||
# Health assessment
|
||||
ignoreDifferences:
|
||||
- group: apps
|
||||
kind: Deployment
|
||||
jsonPointers:
|
||||
- /spec/replicas
|
||||
|
||||
Reference in New Issue
Block a user