# .gitea/workflows/deploy.yml name: Deploy to K3s on: push: branches: - master jobs: deploy: runs-on: ubuntu-latest container: image: localhost:5000/tiny-ci-runner:latest env: IMAGE_TAG: ${{ github.sha }} KUBECONFIG: /tmp/.kube/config NODE_ENV: production steps: - name: Write kubeconfig run: | mkdir -p /tmp/.kube cat << 'EOF' > /tmp/.kube/config ${{ secrets.KUBECONFIG_DATA }} EOF chmod 600 /tmp/.kube/config - name: Verify Kubernetes access run: | kubectl cluster-info kubectl get nodes - name: Checkout code run: | git clone --depth=1 --branch master \ https://git.tonesc.cn/tone/tonePage.git \ /workspace/tone/tonePage cd /workspace/tone/tonePage git log -1 --oneline - name: Build and push backend image run: | cd /workspace/tone/tonePage/apps/backend docker build -t localhost:5000/backend:${IMAGE_TAG} . docker push localhost:5000/backend:${IMAGE_TAG} - name: Build and push frontend image run: | cd /workspace/tone/tonePage/apps/frontend docker build \ --build-arg API_BASE="http://backend-service:3001" \ -t localhost:5000/frontend:${IMAGE_TAG} . docker push localhost:5000/frontend:${IMAGE_TAG} - name: Run database migrations with Kubernetes Job run: | cd /workspace/tone/tonePage/apps/deploy echo "Running database migrations using backend image: localhost:5000/backend:${IMAGE_TAG}" JOB_NAME="backend-migrate-$(echo ${IMAGE_TAG} | cut -c1-8)-$(date +%s)" cat << EOF > /tmp/migration-job-${IMAGE_TAG}.yaml apiVersion: batch/v1 kind: Job metadata: name: $JOB_NAME namespace: default spec: template: spec: restartPolicy: Never containers: - name: migrator image: localhost:5000/backend:${IMAGE_TAG} command: ["pnpm", "run", "migration:run"] env: - name: NODE_ENV value: "production" - name: DATABASE_HOST value: "postgres-service" - name: DATABASE_PORT value: "5432" - name: DATABASE_NAME value: "tone_page" - name: DATABASE_USERNAME value: "tone_page" - name: DATABASE_PASSWORD valueFrom: secretKeyRef: name: backend-secret key: DATABASE_PASSWORD - name: JWT_SECRET valueFrom: secretKeyRef: name: backend-secret key: JWT_SECRET - name: JWT_EXPIRES_IN value: "1d" - name: ALIYUN_ACCESS_KEY_ID valueFrom: secretKeyRef: name: backend-secret key: ALIYUN_ACCESS_KEY_ID - name: ALIYUN_ACCESS_KEY_SECRET valueFrom: secretKeyRef: name: backend-secret key: ALIYUN_ACCESS_KEY_SECRET - name: ALIYUN_OSS_STS_ROLE_ARN valueFrom: secretKeyRef: name: backend-secret key: ALIYUN_OSS_STS_ROLE_ARN - name: WEBAUTHN_RP_ID valueFrom: secretKeyRef: name: backend-secret key: WEBAUTHN_RP_ID - name: WEBAUTHN_ORIGIN valueFrom: secretKeyRef: name: backend-secret key: WEBAUTHN_ORIGIN - name: WEBAUTHN_RP_NAME valueFrom: secretKeyRef: name: backend-secret key: WEBAUTHN_RP_NAME backoffLimit: 3 EOF kubectl apply -f /tmp/migration-job-${IMAGE_TAG}.yaml echo "Waiting for job $JOB_NAME to complete..." kubectl wait --for=condition=complete job/$JOB_NAME --timeout=30s FAILED_COUNT=$(kubectl get job $JOB_NAME -o jsonpath='{.status.failed}' 2>/dev/null || echo "null") if [ "$FAILED_COUNT" = "null" ] || [ "$FAILED_COUNT" -eq 0 ]; then echo "Migration job $JOB_NAME completed successfully." else echo "Migration job $JOB_NAME failed. Failed pod count: $FAILED_COUNT" # 打印 Job 的详细状态和日志以便调试 kubectl describe job $JOB_NAME echo "Logs from the failed pod:" # 获取失败的 Pod 名称并打印其日志 FAILED_POD_NAME=$(kubectl get pods --selector=job-name=$JOB_NAME --field-selector=status.phase=Failed -o jsonpath='{.items[0].metadata.name}') if [ ! -z "$FAILED_POD_NAME" ]; then kubectl logs $FAILED_POD_NAME else echo "Could not find the failed pod name." fi exit 1 fi kubectl delete job $JOB_NAME rm /tmp/migration-job-${IMAGE_TAG}.yaml echo "Database migrations completed successfully." - name: Deploy to K3s run: | cd /workspace/tone/tonePage/apps/deploy # 基础资源 kubectl apply -f postgres-deployment.yaml kubectl apply -f backend-deployment.yaml kubectl apply -f frontend-deployment.yaml # 更新镜像(触发滚动更新) kubectl set image deployment/backend \ backend=localhost:5000/backend:${IMAGE_TAG} kubectl set image deployment/frontend \ frontend=localhost:5000/frontend:${IMAGE_TAG} # 等待滚动完成 kubectl rollout status deployment/backend --timeout=120s kubectl rollout status deployment/frontend --timeout=120s - name: Post-deploy sanity check run: | kubectl get pods kubectl get svc