Testing (P0-7): - 29 functional tests for order-service API (create/pay/complete/cancel lifecycle) - CustomWebApplicationFactory with InMemory DB, mocked wallet/SignalR/tenant - TestAuthHandler for JWT auth in tests - Full lifecycle tests: cash flow and online payment flow end-to-end Staging Deployment (P0-8): - K8s manifests for 8 MVP services + Redis + POS web (namespace, configmap, secrets) - Traefik Ingress with path-based routing and TLS via cert-manager - HPA auto-scaling (2-4 replicas, CPU/memory thresholds) - deploy-staging.sh script with --dry-run and --service flags - CI/CD: deploy-staging.yml and docker-build.yml with matrix strategy - Consistent patterns: port 8080, 3 health probes, RollingUpdate Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
156 lines
4.9 KiB
Bash
Executable File
156 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# EN: Deploy GoodGo Platform MVP services to Kubernetes staging environment
|
|
# VI: Trien khai cac service MVP cua GoodGo Platform len moi truong staging Kubernetes
|
|
#
|
|
# Prerequisites:
|
|
# - kubectl configured with staging cluster access (KUBECONFIG env var)
|
|
# - Docker images pushed to Docker Hub (goodgo/*:staging)
|
|
# - Secrets created via kubectl (see secrets.yaml for template)
|
|
#
|
|
# Usage:
|
|
# export KUBECONFIG=/path/to/kubeconfig
|
|
# ./scripts/deploy/deploy-staging.sh
|
|
# ./scripts/deploy/deploy-staging.sh --service iam-service # Deploy single service
|
|
# ./scripts/deploy/deploy-staging.sh --dry-run # Dry run mode
|
|
|
|
set -euo pipefail
|
|
|
|
# EN: Color output helpers
|
|
# VI: Ham ho tro mau output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/deployments/staging/kubernetes"
|
|
NAMESPACE="staging"
|
|
DRY_RUN=""
|
|
SINGLE_SERVICE=""
|
|
|
|
# EN: Parse arguments
|
|
# VI: Phan tich tham so
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--dry-run)
|
|
DRY_RUN="--dry-run=client"
|
|
echo -e "${YELLOW}[DRY RUN] No changes will be applied${NC}"
|
|
shift
|
|
;;
|
|
--service)
|
|
SINGLE_SERVICE="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo -e "${RED}Unknown option: $1${NC}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# EN: Verify KUBECONFIG
|
|
# VI: Xac minh KUBECONFIG
|
|
if [ -z "${KUBECONFIG:-}" ]; then
|
|
echo -e "${RED}KUBECONFIG environment variable not set${NC}"
|
|
echo "Usage: export KUBECONFIG=/path/to/kubeconfig && $0"
|
|
exit 1
|
|
fi
|
|
|
|
# EN: Verify kubectl connectivity
|
|
# VI: Xac minh ket noi kubectl
|
|
echo -e "${BLUE}Verifying kubectl connectivity...${NC}"
|
|
if ! kubectl cluster-info &>/dev/null; then
|
|
echo -e "${RED}Cannot connect to Kubernetes cluster. Check KUBECONFIG.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}=== GoodGo Platform - Staging Deployment ===${NC}"
|
|
echo -e "${BLUE}Namespace: ${NAMESPACE}${NC}"
|
|
echo -e "${BLUE}Manifests: ${DEPLOY_DIR}${NC}"
|
|
echo ""
|
|
|
|
# EN: Step 1 - Apply namespace
|
|
# VI: Buoc 1 - Tao namespace
|
|
echo -e "${BLUE}[1/5] Applying namespace...${NC}"
|
|
kubectl apply -f "${DEPLOY_DIR}/namespace.yaml" ${DRY_RUN}
|
|
|
|
# EN: Step 2 - Apply shared configuration and secrets
|
|
# VI: Buoc 2 - Ap dung cau hinh chung va secrets
|
|
echo -e "${BLUE}[2/5] Applying configuration and secrets...${NC}"
|
|
kubectl apply -f "${DEPLOY_DIR}/configmap.yaml" ${DRY_RUN}
|
|
# EN: Only apply secrets.yaml if it doesn't contain PLACEHOLDER values
|
|
# VI: Chi ap dung secrets.yaml neu khong chua gia tri PLACEHOLDER
|
|
if grep -q "PLACEHOLDER" "${DEPLOY_DIR}/secrets.yaml"; then
|
|
echo -e "${YELLOW} WARNING: secrets.yaml contains PLACEHOLDER values.${NC}"
|
|
echo -e "${YELLOW} Skipping secrets apply. Use kubectl create secret or sealed-secrets.${NC}"
|
|
echo -e "${YELLOW} See secrets.yaml.example for reference.${NC}"
|
|
else
|
|
kubectl apply -f "${DEPLOY_DIR}/secrets.yaml" ${DRY_RUN}
|
|
fi
|
|
|
|
# EN: Step 3 - Deploy infrastructure (Redis)
|
|
# VI: Buoc 3 - Trien khai ha tang (Redis)
|
|
echo -e "${BLUE}[3/5] Deploying infrastructure...${NC}"
|
|
if [ -z "$SINGLE_SERVICE" ] || [ "$SINGLE_SERVICE" = "redis" ]; then
|
|
kubectl apply -f "${DEPLOY_DIR}/redis.yaml" ${DRY_RUN}
|
|
echo -e "${GREEN} redis deployed${NC}"
|
|
fi
|
|
|
|
# EN: Step 4 - Deploy backend services
|
|
# VI: Buoc 4 - Trien khai cac service backend
|
|
echo -e "${BLUE}[4/5] Deploying services...${NC}"
|
|
|
|
MVP_SERVICES=(
|
|
"iam-service"
|
|
"merchant-service"
|
|
"catalog-service"
|
|
"order-service"
|
|
"fnb-engine"
|
|
"inventory-service"
|
|
"wallet-service"
|
|
"storage-service"
|
|
"pos-web"
|
|
)
|
|
|
|
for svc in "${MVP_SERVICES[@]}"; do
|
|
if [ -z "$SINGLE_SERVICE" ] || [ "$SINGLE_SERVICE" = "$svc" ]; then
|
|
if [ -f "${DEPLOY_DIR}/${svc}.yaml" ]; then
|
|
kubectl apply -f "${DEPLOY_DIR}/${svc}.yaml" ${DRY_RUN}
|
|
echo -e "${GREEN} ${svc} deployed${NC}"
|
|
else
|
|
echo -e "${YELLOW} ${svc}.yaml not found, skipping${NC}"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# EN: Step 5 - Apply ingress routing
|
|
# VI: Buoc 5 - Ap dung dinh tuyen ingress
|
|
echo -e "${BLUE}[5/5] Applying ingress routing...${NC}"
|
|
if [ -z "$SINGLE_SERVICE" ]; then
|
|
kubectl apply -f "${DEPLOY_DIR}/ingress.yaml" ${DRY_RUN}
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${BLUE}Waiting for rollouts to complete...${NC}"
|
|
|
|
if [ -z "$DRY_RUN" ]; then
|
|
for svc in "${MVP_SERVICES[@]}"; do
|
|
if [ -z "$SINGLE_SERVICE" ] || [ "$SINGLE_SERVICE" = "$svc" ]; then
|
|
echo -n " ${svc}: "
|
|
if kubectl rollout status "deployment/${svc}" -n "${NAMESPACE}" --timeout=120s 2>/dev/null; then
|
|
echo -e "${GREEN}ready${NC}"
|
|
else
|
|
echo -e "${YELLOW}still updating (check: kubectl get pods -n ${NAMESPACE} -l app=${svc})${NC}"
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}=== Staging deployment completed ===${NC}"
|
|
echo -e "${BLUE}API: https://api.staging.goodgo.vn${NC}"
|
|
echo -e "${BLUE}POS: https://pos.staging.goodgo.vn${NC}"
|
|
echo ""
|
|
echo -e "Verify: kubectl get pods -n ${NAMESPACE}"
|
|
echo -e "Logs: kubectl logs -n ${NAMESPACE} -l app=<service-name> -f"
|