--- kind: pipeline type: kubernetes name: main-pipeline # Триггер: запускать при изменениях в backend, frontend или .drone.yml trigger: branch: - main - master event: - push steps: # ============================================================ # СБОРКА ОБРАЗОВ (параллельно) # ============================================================ # --- Сборка Backend образа --- - name: build-backend image: plugins/kaniko when: changeset: includes: - backend/** - .drone.yml excludes: - backend/README.md - backend/**/*.md settings: registry: registry.vigdorov.ru repo: registry.vigdorov.ru/library/team-planner-backend dockerfile: backend/Dockerfile context: backend tags: - ${DRONE_COMMIT_SHA:0:7} - latest cache: true cache_repo: registry.vigdorov.ru/library/team-planner-backend-cache username: from_secret: HARBOR_USER password: from_secret: HARBOR_PASSWORD no_push_metadata: true # --- Сборка Frontend образа (параллельно с backend) --- - name: build-frontend image: plugins/kaniko when: changeset: includes: - frontend/** - .drone.yml excludes: - frontend/README.md - frontend/**/*.md settings: registry: registry.vigdorov.ru repo: registry.vigdorov.ru/library/team-planner-frontend dockerfile: frontend/Dockerfile context: frontend tags: - ${DRONE_COMMIT_SHA:0:7} - latest cache: true cache_repo: registry.vigdorov.ru/library/team-planner-frontend-cache username: from_secret: HARBOR_USER password: from_secret: HARBOR_PASSWORD no_push_metadata: true # ============================================================ # ДЕПЛОЙ (только после завершения ОБЕИХ сборок) # ============================================================ # --- Развертывание Backend в PROD --- - name: deploy-backend image: alpine/k8s:1.28.2 depends_on: - build-backend - build-frontend when: changeset: includes: - backend/** - .drone.yml excludes: - backend/README.md - backend/**/*.md environment: KUBE_CONFIG_CONTENT: from_secret: KUBE_CONFIG commands: - mkdir -p ~/.kube - echo "$KUBE_CONFIG_CONTENT" > ~/.kube/config - chmod 600 ~/.kube/config - sed -i "s|https://127.0.0.1:6443|https://10.10.10.100:6443|g" ~/.kube/config - export APP_NAMESPACE="team-planner" - export IMAGE_TAG="${DRONE_COMMIT_SHA:0:7}" - export BACKEND_IMAGE="registry.vigdorov.ru/library/team-planner-backend" - kubectl cluster-info - sed -e "s|__BACKEND_IMAGE__|$BACKEND_IMAGE:$IMAGE_TAG|g" k8s/backend-deployment.yaml | kubectl apply -n $APP_NAMESPACE -f - - kubectl apply -n $APP_NAMESPACE -f k8s/backend-service.yaml - echo "📋 Waiting for rollout..." - echo "=== CURRENT PODS STATE (before rollout) ===" - kubectl get pods -n $APP_NAMESPACE -l app=team-planner-backend -o wide - | if ! kubectl rollout status deployment/team-planner-backend -n $APP_NAMESPACE --timeout=120s; then echo "❌ Rollout failed! Collecting diagnostics..." echo "" echo "=== DEPLOYMENT STATUS ===" kubectl get deployment team-planner-backend -n $APP_NAMESPACE -o wide echo "" echo "=== PODS STATUS ===" kubectl get pods -n $APP_NAMESPACE -l app=team-planner-backend -o wide echo "" echo "=== DESCRIBE DEPLOYMENT ===" kubectl describe deployment team-planner-backend -n $APP_NAMESPACE echo "" echo "=== RECENT EVENTS ===" kubectl get events -n $APP_NAMESPACE --sort-by='.lastTimestamp' | tail -30 echo "" echo "=== POD LOGS (last 100 lines) ===" POD_NAME=$(kubectl get pods -n $APP_NAMESPACE -l app=team-planner-backend -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "") if [ -n "$POD_NAME" ]; then kubectl logs $POD_NAME -n $APP_NAMESPACE --tail=100 2>/dev/null || echo "No logs available" echo "" echo "=== DESCRIBE POD ===" kubectl describe pod $POD_NAME -n $APP_NAMESPACE else echo "No pods found" fi exit 1 fi - echo "✅ Backend deployed to PROD (image:$IMAGE_TAG)" # --- Развертывание Frontend в PROD --- - name: deploy-frontend image: alpine/k8s:1.28.2 depends_on: - build-backend - build-frontend when: changeset: includes: - frontend/** - .drone.yml excludes: - frontend/README.md - frontend/**/*.md environment: KUBE_CONFIG_CONTENT: from_secret: KUBE_CONFIG commands: - mkdir -p ~/.kube - echo "$KUBE_CONFIG_CONTENT" > ~/.kube/config - chmod 600 ~/.kube/config - sed -i "s|https://127.0.0.1:6443|https://10.10.10.100:6443|g" ~/.kube/config - export APP_NAMESPACE="team-planner" - export IMAGE_TAG="${DRONE_COMMIT_SHA:0:7}" - export FRONTEND_IMAGE="registry.vigdorov.ru/library/team-planner-frontend" - kubectl cluster-info - sed -e "s|__FRONTEND_IMAGE__|$FRONTEND_IMAGE:$IMAGE_TAG|g" k8s/frontend-deployment.yaml | kubectl apply -n $APP_NAMESPACE -f - - kubectl apply -n $APP_NAMESPACE -f k8s/frontend-service.yaml - echo "📋 Waiting for rollout..." - | if ! kubectl rollout status deployment/team-planner-frontend -n $APP_NAMESPACE --timeout=300s; then echo "❌ Rollout failed! Collecting diagnostics..." echo "" echo "=== DEPLOYMENT STATUS ===" kubectl get deployment team-planner-frontend -n $APP_NAMESPACE -o wide echo "" echo "=== PODS STATUS ===" kubectl get pods -n $APP_NAMESPACE -l app=team-planner-frontend -o wide echo "" echo "=== DESCRIBE DEPLOYMENT ===" kubectl describe deployment team-planner-frontend -n $APP_NAMESPACE echo "" echo "=== RECENT EVENTS ===" kubectl get events -n $APP_NAMESPACE --sort-by='.lastTimestamp' | tail -30 echo "" echo "=== POD LOGS (last 100 lines) ===" POD_NAME=$(kubectl get pods -n $APP_NAMESPACE -l app=team-planner-frontend -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "") if [ -n "$POD_NAME" ]; then kubectl logs $POD_NAME -n $APP_NAMESPACE --tail=100 2>/dev/null || echo "No logs available" echo "" echo "=== DESCRIBE POD ===" kubectl describe pod $POD_NAME -n $APP_NAMESPACE else echo "No pods found" fi exit 1 fi - echo "✅ Frontend deployed to PROD (image:$IMAGE_TAG)" --- kind: pipeline type: kubernetes name: infra-pipeline # Триггер: запускать только при изменениях в k8s конфигах trigger: branch: - main - master event: - push paths: include: - k8s/** steps: # --- Создание секретов (УДАЛИТЬ ПОСЛЕ ПЕРВОГО ДЕПЛОЯ) --- - name: create-secrets image: alpine/k8s:1.28.2 environment: KUBE_CONFIG_CONTENT: from_secret: KUBE_CONFIG DB_NAME: from_secret: DB_NAME DB_USER: from_secret: DB_USER DB_PASSWORD: from_secret: DB_PASSWORD commands: - mkdir -p ~/.kube - echo "$KUBE_CONFIG_CONTENT" > ~/.kube/config - chmod 600 ~/.kube/config - sed -i "s|https://127.0.0.1:6443|https://10.10.10.100:6443|g" ~/.kube/config - export APP_NAMESPACE="team-planner" - kubectl create namespace $APP_NAMESPACE --dry-run=client -o yaml | kubectl apply -f - - | kubectl create secret generic team-planner-secrets \ --from-literal=db-name="$DB_NAME" \ --from-literal=db-user="$DB_USER" \ --from-literal=db-password="$DB_PASSWORD" \ --namespace=$APP_NAMESPACE \ --dry-run=client -o yaml | kubectl apply -f - - echo "✅ Secrets created/updated" # --- Развертывание инфраструктуры (PostgreSQL, Services, Ingress) --- - name: deploy-infra image: alpine/k8s:1.28.2 depends_on: - create-secrets environment: KUBE_CONFIG_CONTENT: from_secret: KUBE_CONFIG commands: - mkdir -p ~/.kube - echo "$KUBE_CONFIG_CONTENT" > ~/.kube/config - chmod 600 ~/.kube/config - sed -i "s|https://127.0.0.1:6443|https://10.10.10.100:6443|g" ~/.kube/config - export APP_NAMESPACE="team-planner" - export HOSTNAME="team-planner.vigdorov.ru" - export SECRET_NAME="wildcard-cert" - kubectl cluster-info - kubectl create namespace $APP_NAMESPACE --dry-run=client -o yaml | kubectl apply -f - - kubectl apply -n $APP_NAMESPACE -f k8s/postgres-pvc.yaml - kubectl apply -n $APP_NAMESPACE -f k8s/postgres-statefulset.yaml - kubectl apply -n $APP_NAMESPACE -f k8s/postgres-service.yaml - kubectl apply -n $APP_NAMESPACE -f k8s/backend-service.yaml - kubectl apply -n $APP_NAMESPACE -f k8s/frontend-service.yaml - sed -e "s|__HOSTNAME__|$HOSTNAME|g" -e "s|__SECRET_NAME__|$SECRET_NAME|g" k8s/ingress.yaml | kubectl apply -n $APP_NAMESPACE -f - - echo "✅ Infrastructure updated"