kind: pipeline type: docker name: ai-flow-backend-prod-deploy steps: # 步骤1: 将代码同步到远程服务器 - name: sync-code image: appleboy/drone-scp settings: host: from_secret: PROD_HOST username: from_secret: PROD_USER key: from_secret: PROD_SSH_KEY port: 22 target: /data/ai_flow_backend-prod/source source: - . rm_target: true strip_components: 0 # 步骤2: SSH到远程服务器执行构建和单实例部署 - name: build-and-deploy image: appleboy/drone-ssh settings: host: from_secret: PROD_HOST username: from_secret: PROD_USER key: from_secret: PROD_SSH_KEY port: 22 command_timeout: 20m envs: - DRONE_TAG script: - echo "===== 开始构建版本:${DRONE_TAG} =====" - cd /data/ai_flow_backend-prod/source # 删除旧镜像 - docker rmi ai-flow-backend-prod:latest || true # 构建新镜像 - docker build -f Dockerfile-prod -t ai-flow-backend-prod:${DRONE_TAG} -t ai-flow-backend-prod:latest . # ===== 清理旧单实例容器 ===== - | if docker ps -a --format '{{.Names}}' | grep -q '^ai-flow-backend-prod$'; then echo "检测到旧单实例容器 ai-flow-backend-prod,先清理" docker stop ai-flow-backend-prod || true docker rm ai-flow-backend-prod || true fi # ===== 部署单实例 ===== - echo "===== 部署单实例 ai-flow-backend-prod =====" # 启动新容器(宿主机映射为8004,容器内为8002) - | docker run -d \ --name ai-flow-backend-prod \ --restart always \ -p 8004:8002 \ -v /data/ai_flow_backend-prod/uploads:/app/uploads \ -v /data/ai_flow_backend-prod/logs:/app/logs \ ai-flow-backend-prod:${DRONE_TAG} # 等待容器启动 - | HEALTH_OK=false for i in $(seq 1 30); do # 如果有健康检查接口,请替换为 curl,例如:curl -sf http://127.0.0.1:8002/health # 这里先用 docker inspect 判断是否处于 running 状态 if [ "$(docker inspect -f '{{.State.Running}}' ai-flow-backend-prod)" = "true" ]; then echo "ai-flow-backend-prod 启动成功" HEALTH_OK=true break fi echo "等待容器启动... ($i/30)" sleep 2 done if [ "$HEALTH_OK" != "true" ]; then echo "ERROR: ai-flow-backend-prod 启动超时" exit 1 fi # ===== 清理无用的悬空镜像 ===== - docker image prune -f - echo "===== 单实例部署完成:ai-flow-backend-prod:${DRONE_TAG} =====" trigger: event: - tag