Quick reference for deploying Ciyex EHR UI to Kubernetes using GitHub Actions and Kustomize.
-
Deploy to Stage: Push or merge to
mainbranchgit checkout main git pull origin main # Make changes... git push origin main→ Automatically deploys to https://stg.ciyex.com
-
Deploy to Production: Create and push a release branch
git checkout main git pull origin main git checkout -b release/v1.0.0 git push origin release/v1.0.0
→ Automatically deploys to https://app.ciyex.com
If you need to deploy manually:
# Stage
kubectl apply -k k8s/overlays/stage
# Production
kubectl apply -k k8s/overlays/prodAdd these in Settings → Secrets and variables → Actions:
| Secret Name | Description | Example |
|---|---|---|
AZURE_CREDENTIALS_STAGE |
Azure service principal JSON for stage | {"clientId":"...","clientSecret":"..."} |
AZURE_CREDENTIALS_PROD |
Azure service principal JSON for prod | {"clientId":"...","clientSecret":"..."} |
TEAMS_WEBHOOK_URL |
Microsoft Teams webhook (optional) | https://...webhook.office.com/... |
| Environment | ACR | Cluster | Resource Group |
|---|---|---|---|
| Stage | hinikubestageacr.azurecr.io |
hiniKubeStage |
hiniKubeStage-rg |
| Production | hinikubestageacr.azurecr.io |
hiniKubeProd |
hiniKubeProd-rg |
Configure in Settings → Environments:
Production Environment:
- Add required reviewers
- Add deployment branch rule:
release/** - Set environment URL:
https://app.ciyex.com
┌─────────────────┐
│ Feature Branch │
└────────┬────────┘
│ Create PR
↓
┌─────────────────┐
│ PR Checks │ ← Lint, Type Check, Tests (deploy-stage.yml)
└────────┬────────┘
│ Merge
↓
┌─────────────────┐
│ Main Branch │
└────────┬────────┘
│ Auto Deploy (deploy-stage.yml)
↓
┌─────────────────┐
│ Stage (stg) │ ← https://stg.ciyex.com
└────────┬────────┘
│ Create release branch
↓
┌─────────────────┐
│ Release Branch │
└────────┬────────┘
│ Auto Deploy (deploy-prod.yml)
↓
┌─────────────────┐
│ Prod (app) │ ← https://app.ciyex.com
└─────────────────┘
# Stage
kubectl get deployment ciyex-ehr-ui-stage
kubectl get pods -l app=ciyex-ehr-ui
# Production
kubectl get deployment ciyex-ehr-ui-prod
kubectl get pods -l app=ciyex-ehr-ui# Stage
kubectl logs -l app=ciyex-ehr-ui -n default --tail=100 -f
# Production
kubectl logs -l app=ciyex-ehr-ui -n default --tail=100 -f# Stage
kubectl get ingress ciyex-ehr-ui-ingress-stage
kubectl describe ingress ciyex-ehr-ui-ingress-stage
# Production
kubectl get ingress ciyex-ehr-ui-ingress-prod
kubectl describe ingress ciyex-ehr-ui-ingress-prod# Stage
kubectl rollout undo deployment/ciyex-ehr-ui-stage
# Production
kubectl rollout undo deployment/ciyex-ehr-ui-prodRe-run a previous successful workflow from the Actions tab.
# Check pod status
kubectl get pods -l app=ciyex-ehr-ui
# Describe pod for events
kubectl describe pod <pod-name>
# Check logs
kubectl logs <pod-name># Verify image exists
docker pull ghcr.io/<your-org>/ciyex-ehr-ui:<tag>
# Check image pull secrets
kubectl get secrets# Check ingress controller
kubectl get pods -n ingress-nginx
# Check certificate
kubectl get certificate
kubectl describe certificate ciyex-ehr-ui-stage-tls.
├── .github/
│ └── workflows/
│ ├── deploy-stage.yml # Stage deployment workflow
│ ├── deploy-prod.yml # Production deployment workflow
│ └── README.md # Workflow documentation
├── k8s/
│ ├── base/ # Base Kubernetes manifests
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ ├── ingress.yaml
│ │ └── kustomization.yaml
│ ├── overlays/
│ │ ├── stage/ # Stage environment
│ │ │ ├── kustomization.yaml
│ │ │ ├── deployment-patch.yaml
│ │ │ └── ingress-patch.yaml
│ │ └── prod/ # Production environment
│ │ ├── kustomization.yaml
│ │ ├── deployment-patch.yaml
│ │ └── ingress-patch.yaml
│ └── README.md # Kubernetes documentation
├── Dockerfile # Docker build configuration
├── .dockerignore # Docker ignore patterns
└── DEPLOYMENT.md # This file
NODE_ENV=stagingNEXT_PUBLIC_ENV=stagingNEXT_PUBLIC_API_URL=https://stg.ciyex.com/api
NODE_ENV=productionNEXT_PUBLIC_ENV=productionNEXT_PUBLIC_API_URL=https://app.ciyex.com/api
- Stage: 1 replica, no resource limits
- Production: 2 replicas, 512Mi-1Gi memory, 250m-500m CPU
For issues or questions:
- Check GitHub Actions logs
- Review Kubernetes events:
kubectl get events --sort-by='.lastTimestamp' - Check application logs
- Review this documentation