327 lines
11 KiB
YAML
327 lines
11 KiB
YAML
---
|
||
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
|
||
|
||
# --- Сборка Keycloak темы (только при изменениях в keycloak-theme/) ---
|
||
- name: build-keycloak-theme
|
||
image: plugins/kaniko
|
||
when:
|
||
changeset:
|
||
includes:
|
||
- keycloak-theme/**
|
||
excludes:
|
||
- keycloak-theme/README.md
|
||
- keycloak-theme/**/*.md
|
||
settings:
|
||
registry: registry.vigdorov.ru
|
||
repo: registry.vigdorov.ru/library/keycloak-team-planner
|
||
dockerfile: keycloak-theme/Dockerfile
|
||
context: keycloak-theme
|
||
tags:
|
||
- ${DRONE_COMMIT_SHA:0:7}
|
||
- "26.5.0"
|
||
- latest
|
||
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)"
|
||
|
||
# --- Развертывание Keycloak темы (только при изменениях в keycloak-theme/) ---
|
||
- name: deploy-keycloak-theme
|
||
image: alpine/k8s:1.28.2
|
||
depends_on:
|
||
- build-keycloak-theme
|
||
when:
|
||
changeset:
|
||
includes:
|
||
- keycloak-theme/**
|
||
excludes:
|
||
- keycloak-theme/README.md
|
||
- keycloak-theme/**/*.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 KEYCLOAK_NAMESPACE="auth"
|
||
- export IMAGE_TAG="${DRONE_COMMIT_SHA:0:7}"
|
||
- export KEYCLOAK_IMAGE="registry.vigdorov.ru/library/keycloak-team-planner:$IMAGE_TAG"
|
||
- kubectl cluster-info
|
||
- kubectl set image statefulset/keycloak-keycloakx keycloak=$KEYCLOAK_IMAGE -n $KEYCLOAK_NAMESPACE
|
||
- echo "📋 Waiting for rollout..."
|
||
- |
|
||
if ! kubectl rollout status statefulset/keycloak-keycloakx -n $KEYCLOAK_NAMESPACE --timeout=180s; then
|
||
echo "❌ Rollout failed! Collecting diagnostics..."
|
||
kubectl get pods -n $KEYCLOAK_NAMESPACE -l app.kubernetes.io/name=keycloakx -o wide
|
||
kubectl describe statefulset keycloak-keycloakx -n $KEYCLOAK_NAMESPACE
|
||
exit 1
|
||
fi
|
||
- echo "✅ Keycloak theme deployed (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"
|