From 36ff1b5acab0c866b80e31189387f1f82d30e2aa Mon Sep 17 00:00:00 2001 From: zyc <1439655764@qq.com> Date: Sat, 4 Apr 2026 11:18:17 +0800 Subject: [PATCH] fix build dev --- .gitea/workflows/deploy.yaml | 150 +++++++++++++++++++++-------------- k8s/backend-deployment.yaml | 21 ++--- k8s/celery-deployment.yaml | 21 ++--- k8s/cert-manager-issuer.yaml | 2 +- k8s/web-deployment.yaml | 2 - 5 files changed, 100 insertions(+), 96 deletions(-) diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index 6296748..1e2affe 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -3,102 +3,130 @@ name: Build and Deploy on: push: branches: - - main - master + - dev jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + run: | + git clone --depth=1 --branch=${{ github.ref_name }} https://gitea.airlabs.art/${{ github.repository }}.git . - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - config-inline: | - [registry."docker.io"] - mirrors = ["https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev"] + - name: Set environment by branch + run: | + SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) + BUILD_DATE=$(date +%Y%m%d) - - name: Login to Huawei Cloud SWR - uses: docker/login-action@v2 - with: - registry: ${{ secrets.SWR_SERVER }} - username: ${{ secrets.SWR_USERNAME }} - password: ${{ secrets.SWR_PASSWORD }} + if [[ "${{ github.ref_name }}" == "master" ]]; then + echo "IMAGE_TAG=prod-${BUILD_DATE}-${SHORT_SHA}" >> $GITHUB_ENV + echo "CR_ORG=prod" >> $GITHUB_ENV + echo "DEPLOY_ENV=production" >> $GITHUB_ENV + echo "DOMAIN_API=airflow-studio-api.airlabs.art" >> $GITHUB_ENV + echo "DOMAIN_WEB=airflow-studio.airlabs.art" >> $GITHUB_ENV + echo "REDIS_URL=redis://zyc:Zyc188208@redis-shzlf5t46gjvow7ua.redis.ivolces.com:6379/0" >> $GITHUB_ENV + elif [[ "${{ github.ref_name }}" == "dev" ]]; then + echo "IMAGE_TAG=dev-${BUILD_DATE}-${SHORT_SHA}" >> $GITHUB_ENV + echo "CR_ORG=dev" >> $GITHUB_ENV + echo "DEPLOY_ENV=development" >> $GITHUB_ENV + echo "DOMAIN_API=airflow-studio-api.test.airlabs.art" >> $GITHUB_ENV + echo "DOMAIN_WEB=airflow-studio.test.airlabs.art" >> $GITHUB_ENV + echo "REDIS_URL=redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.ivolces.com:6379/0" >> $GITHUB_ENV + fi + + - name: Login to Volcano Engine CR + run: | + echo "${{ secrets.CR_PASSWORD }}" | docker login --username "${{ secrets.CR_USERNAME }}" --password-stdin ${{ secrets.CR_SERVER }} - name: Build and Push Backend id: build_backend run: | set -o pipefail - docker buildx build \ - --push \ - --no-cache \ - --provenance=false \ - --tag ${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/video-backend:latest \ + DOCKER_BUILDKIT=0 docker build \ + --tag ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-backend:${{ env.IMAGE_TAG }} \ + --tag ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-backend:latest \ ./backend 2>&1 | tee /tmp/build.log + docker push ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-backend:${{ env.IMAGE_TAG }} + docker push ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-backend:latest - name: Build and Push Web id: build_web run: | set -o pipefail - docker buildx build \ - --push \ - --provenance=false \ - --tag ${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/video-web:latest \ + DOCKER_BUILDKIT=0 docker build \ + --tag ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-web:${{ env.IMAGE_TAG }} \ + --tag ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-web:latest \ ./web 2>&1 | tee -a /tmp/build.log + docker push ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-web:${{ env.IMAGE_TAG }} + docker push ${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}/video-web:latest - - name: Setup SSH + - name: Setup Kubectl + run: kubectl version --client + + - name: Set kubeconfig run: | - mkdir -p ~/.ssh - echo "${{ secrets.K3S_SSH_KEY }}" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H ${{ secrets.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null + mkdir -p $HOME/.kube + if [[ "${{ github.ref_name }}" == "master" ]]; then + echo "${{ secrets.VOLCANO_PROD_KUBE_CONFIG }}" > $HOME/.kube/config + elif [[ "${{ github.ref_name }}" == "dev" ]]; then + echo "${{ secrets.VOLCANO_TEST_KUBE_CONFIG }}" > $HOME/.kube/config + fi + chmod 600 $HOME/.kube/config - - name: Deploy to K3s via SSH + - name: Deploy to K3s id: deploy run: | - SWR_IMAGE="${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}" + echo "Environment: ${{ env.DEPLOY_ENV }}" + CR_IMAGE="${{ secrets.CR_SERVER }}/${{ env.CR_ORG }}" - # Replace image placeholders in yaml files - sed -i "s|\${CI_REGISTRY_IMAGE}/video-backend:latest|${SWR_IMAGE}/video-backend:latest|g" k8s/backend-deployment.yaml - sed -i "s|\${CI_REGISTRY_IMAGE}/video-backend:latest|${SWR_IMAGE}/video-backend:latest|g" k8s/celery-deployment.yaml - sed -i "s|\${CI_REGISTRY_IMAGE}/video-web:latest|${SWR_IMAGE}/video-web:latest|g" k8s/web-deployment.yaml + # Replace image placeholders + sed -i "s|\${CI_REGISTRY_IMAGE}/video-backend:latest|${CR_IMAGE}/video-backend:${{ env.IMAGE_TAG }}|g" k8s/backend-deployment.yaml + sed -i "s|\${CI_REGISTRY_IMAGE}/video-backend:latest|${CR_IMAGE}/video-backend:${{ env.IMAGE_TAG }}|g" k8s/celery-deployment.yaml + sed -i "s|\${CI_REGISTRY_IMAGE}/video-web:latest|${CR_IMAGE}/video-web:${{ env.IMAGE_TAG }}|g" k8s/web-deployment.yaml - # Copy k8s manifests to server - scp -o StrictHostKeyChecking=no k8s/backend-deployment.yaml k8s/web-deployment.yaml k8s/ingress.yaml k8s/celery-deployment.yaml root@${{ secrets.K3S_HOST }}:/tmp/ + # Replace domain placeholders in ingress + sed -i "s|airflow-studio-api.airlabs.art|${{ env.DOMAIN_API }}|g" k8s/ingress.yaml + sed -i "s|airflow-studio.airlabs.art|${{ env.DOMAIN_WEB }}|g" k8s/ingress.yaml - # Create/update secrets and apply manifests on server + # Replace DB config for production + if [[ "${{ env.DEPLOY_ENV }}" == "production" ]]; then + sed -i "s|mysql-8351f937d637.rds.ivolces.com|mysqld9bb4e81696d.rds.ivolces.com|g" k8s/backend-deployment.yaml + sed -i "s|mysql-8351f937d637.rds.ivolces.com|mysqld9bb4e81696d.rds.ivolces.com|g" k8s/celery-deployment.yaml + fi + + # Replace CORS origin + sed -i "s|https://airflow-studio.airlabs.art|https://${{ env.DOMAIN_WEB }}|g" k8s/backend-deployment.yaml + + # Replace Redis URL by environment + sed -i "s|redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.ivolces.com:6379/0|${{ env.REDIS_URL }}|g" k8s/backend-deployment.yaml + sed -i "s|redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.ivolces.com:6379/0|${{ env.REDIS_URL }}|g" k8s/celery-deployment.yaml + + # Create/update secrets (业务密钥,DB 已写在 yaml 里) + kubectl create secret generic video-backend-secrets \ + --from-literal=ARK_API_KEY='${{ secrets.ARK_API_KEY }}' \ + --from-literal=TOS_ACCESS_KEY='${{ secrets.TOS_ACCESS_KEY }}' \ + --from-literal=TOS_SECRET_KEY='${{ secrets.TOS_SECRET_KEY }}' \ + --from-literal=DJANGO_SECRET_KEY='${{ secrets.DJANGO_SECRET_KEY }}' \ + --from-literal=ALIYUN_SMS_ACCESS_KEY='${{ secrets.ALIYUN_SMS_ACCESS_KEY }}' \ + --from-literal=ALIYUN_SMS_ACCESS_SECRET='${{ secrets.ALIYUN_SMS_ACCESS_SECRET }}' \ + --dry-run=client -o yaml | kubectl apply -f - + + # Apply manifests set -o pipefail - ssh -o StrictHostKeyChecking=no root@${{ secrets.K3S_HOST }} << ENDSSH - export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + { + kubectl apply -f k8s/backend-deployment.yaml + kubectl apply -f k8s/celery-deployment.yaml + kubectl apply -f k8s/web-deployment.yaml + kubectl apply -f k8s/ingress.yaml - kubectl create secret generic video-backend-secrets \ - --from-literal=ARK_API_KEY='${{ secrets.ARK_API_KEY }}' \ - --from-literal=TOS_ACCESS_KEY='${{ secrets.TOS_ACCESS_KEY }}' \ - --from-literal=TOS_SECRET_KEY='${{ secrets.TOS_SECRET_KEY }}' \ - --from-literal=DJANGO_SECRET_KEY='${{ secrets.DJANGO_SECRET_KEY }}' \ - --from-literal=DB_HOST='${{ secrets.DB_HOST }}' \ - --from-literal=DB_USER='${{ secrets.DB_USER }}' \ - --from-literal=DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \ - --from-literal=ALIYUN_SMS_ACCESS_KEY='${{ secrets.ALIYUN_SMS_ACCESS_KEY }}' \ - --from-literal=ALIYUN_SMS_ACCESS_SECRET='${{ secrets.ALIYUN_SMS_ACCESS_SECRET }}' \ - --dry-run=client -o yaml | kubectl apply -f - - - kubectl apply -f /tmp/backend-deployment.yaml - kubectl apply -f /tmp/celery-deployment.yaml - kubectl apply -f /tmp/web-deployment.yaml - kubectl apply -f /tmp/ingress.yaml - - # Preserve real client IP: disable SNAT on Traefik + # Preserve real client IP kubectl patch svc traefik -n kube-system -p '{"spec":{"externalTrafficPolicy":"Local"}}' 2>/dev/null || true kubectl rollout restart deployment/video-backend kubectl rollout restart deployment/celery-worker kubectl rollout restart deployment/video-web - - rm -f /tmp/backend-deployment.yaml /tmp/web-deployment.yaml /tmp/ingress.yaml /tmp/celery-deployment.yaml - ENDSSH + } 2>&1 | tee /tmp/deploy.log # ===== Log Center: failure reporting ===== - name: Report failure to Log Center @@ -137,7 +165,7 @@ jobs: -H "Content-Type: application/json" \ -d "{ \"project_id\": \"video_backend\", - \"environment\": \"${{ github.ref_name }}\", + \"environment\": \"${{ env.DEPLOY_ENV }}\", \"level\": \"ERROR\", \"source\": \"${SOURCE}\", \"commit_hash\": \"${{ github.sha }}\", diff --git a/k8s/backend-deployment.yaml b/k8s/backend-deployment.yaml index f457441..7a300dc 100644 --- a/k8s/backend-deployment.yaml +++ b/k8s/backend-deployment.yaml @@ -14,8 +14,6 @@ spec: labels: app: video-backend spec: - imagePullSecrets: - - name: swr-secret containers: - name: video-backend image: ${CI_REGISTRY_IMAGE}/video-backend:latest @@ -34,29 +32,20 @@ spec: secretKeyRef: name: video-backend-secrets key: DJANGO_SECRET_KEY - # Database (Aliyun RDS) + # Database (Volcano Engine RDS - 默认测试环境,生产环境通过 CI 替换) - name: DB_HOST - valueFrom: - secretKeyRef: - name: video-backend-secrets - key: DB_HOST + value: "mysql-8351f937d637.rds.ivolces.com" - name: DB_NAME value: "video_auto" - name: DB_USER - valueFrom: - secretKeyRef: - name: video-backend-secrets - key: DB_USER + value: "zyc" - name: DB_PASSWORD - valueFrom: - secretKeyRef: - name: video-backend-secrets - key: DB_PASSWORD + value: "Zyc188208" - name: DB_PORT value: "3306" # Redis (Celery broker) - name: REDIS_URL - value: "redis://:vAhRnAA6VMco@redis-cngzyc2r77ka16g7a.redis.ivolces.com:6379/0" + value: "redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.ivolces.com:6379/0" # CORS - name: CORS_ALLOWED_ORIGINS value: "https://airflow-studio.airlabs.art" diff --git a/k8s/celery-deployment.yaml b/k8s/celery-deployment.yaml index d7f99f4..40b0613 100644 --- a/k8s/celery-deployment.yaml +++ b/k8s/celery-deployment.yaml @@ -14,8 +14,6 @@ spec: labels: app: celery-worker spec: - imagePullSecrets: - - name: swr-secret containers: - name: celery-worker image: ${CI_REGISTRY_IMAGE}/video-backend:latest @@ -35,25 +33,16 @@ spec: key: DJANGO_SECRET_KEY # Redis - name: REDIS_URL - value: "redis://:vAhRnAA6VMco@redis-cngzyc2r77ka16g7a.redis.ivolces.com:6379/0" - # Database (Aliyun RDS) + value: "redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.ivolces.com:6379/0" + # Database (Volcano Engine RDS - 默认测试环境,生产环境通过 CI 替换) - name: DB_HOST - valueFrom: - secretKeyRef: - name: video-backend-secrets - key: DB_HOST + value: "mysql-8351f937d637.rds.ivolces.com" - name: DB_NAME value: "video_auto" - name: DB_USER - valueFrom: - secretKeyRef: - name: video-backend-secrets - key: DB_USER + value: "zyc" - name: DB_PASSWORD - valueFrom: - secretKeyRef: - name: video-backend-secrets - key: DB_PASSWORD + value: "Zyc188208" - name: DB_PORT value: "3306" # TOS (from Secret) diff --git a/k8s/cert-manager-issuer.yaml b/k8s/cert-manager-issuer.yaml index 006121b..b78a0e3 100644 --- a/k8s/cert-manager-issuer.yaml +++ b/k8s/cert-manager-issuer.yaml @@ -12,4 +12,4 @@ spec: solvers: - http01: ingress: - class: alb + class: traefik diff --git a/k8s/web-deployment.yaml b/k8s/web-deployment.yaml index 572da96..121435b 100644 --- a/k8s/web-deployment.yaml +++ b/k8s/web-deployment.yaml @@ -14,8 +14,6 @@ spec: labels: app: video-web spec: - imagePullSecrets: - - name: swr-secret containers: - name: video-web image: ${CI_REGISTRY_IMAGE}/video-web:latest