From ae7ce722273a50c4f2436c942b5c1c71f27672bc Mon Sep 17 00:00:00 2001 From: penghanyuan Date: Thu, 14 May 2026 17:16:56 +0200 Subject: [PATCH] fix(ci): reduce SSH broken pipe during remote image pull Add stable SSH keepalive/connect options and retry the remote docker pull candidate step so transient runner-network disconnects no longer fail deployment immediately. Co-authored-by: Cursor --- .github/workflows/docker-build-deploy.yml | 38 ++++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker-build-deploy.yml b/.github/workflows/docker-build-deploy.yml index 444493e..2135efd 100644 --- a/.github/workflows/docker-build-deploy.yml +++ b/.github/workflows/docker-build-deploy.yml @@ -220,6 +220,9 @@ jobs: echo "COMPOSE_DIR=${{ secrets.DEPLOY_PATH || '/opt/life-echo' }}" } >> "$GITHUB_ENV" fi + { + echo "SSH_BASE_OPTS=-o BatchMode=yes -o ConnectTimeout=15 -o ConnectionAttempts=3 -o ServerAliveInterval=20 -o ServerAliveCountMax=6 -o TCPKeepAlive=yes" + } >> "$GITHUB_ENV" - name: Add server to known hosts run: | @@ -238,7 +241,7 @@ jobs: done if [ "$KEYSCAN_OK" -eq 1 ]; then - echo "SSH_COMMON_OPTS=" >> "$GITHUB_ENV" + echo "SSH_COMMON_OPTS=${SSH_BASE_OPTS}" >> "$GITHUB_ENV" else echo "::warning::ssh-keyscan failed. Falling back to non-strict host checking for this run." if [ -f /tmp/ssh-keyscan.err ]; then @@ -246,7 +249,7 @@ jobs: cat /tmp/ssh-keyscan.err || true echo "--------------------------" fi - echo "SSH_COMMON_OPTS=-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" >> "$GITHUB_ENV" + echo "SSH_COMMON_OPTS=${SSH_BASE_OPTS} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" >> "$GITHUB_ENV" fi - name: Prepare remote candidate release @@ -298,15 +301,28 @@ jobs: scp ${SSH_COMMON_OPTS:-} -P "$SSH_PORT" ./api/docker-compose.yml "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/docker-compose.candidate.yml" scp ${SSH_COMMON_OPTS:-} -P "$SSH_PORT" "$ENV_SRC" "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/.env.candidate" - ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " - set -euo pipefail - cd '$COMPOSE_DIR/api' - echo '拉取候选镜像: $IMAGE_TAG' - docker pull '$IMAGE_TAG' - sed -i.tmp 's|image:.*lifecho-api.*|image: $IMAGE_TAG|g' docker-compose.candidate.yml - sed -i.tmp 's|image:.*life-echo-api.*|image: $IMAGE_TAG|g' docker-compose.candidate.yml - rm -f docker-compose.candidate.yml.tmp 2>/dev/null || true - " + PULL_OK=0 + for i in 1 2 3; do + echo "远端拉取候选镜像尝试 ${i}/3..." + if ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " + set -euo pipefail + cd '$COMPOSE_DIR/api' + echo '拉取候选镜像: $IMAGE_TAG' + docker pull '$IMAGE_TAG' + sed -i.tmp 's|image:.*lifecho-api.*|image: $IMAGE_TAG|g' docker-compose.candidate.yml + sed -i.tmp 's|image:.*life-echo-api.*|image: $IMAGE_TAG|g' docker-compose.candidate.yml + rm -f docker-compose.candidate.yml.tmp 2>/dev/null || true + "; then + PULL_OK=1 + break + fi + sleep 3 + done + + if [ "$PULL_OK" -ne 1 ]; then + echo "::error::远端拉取候选镜像连续 3 次失败。" + exit 1 + fi - name: Promote candidate release env: