fix(ci): harden SSH host setup in API deploy workflow
Add retries for ssh-keyscan and fall back to non-strict host checking for transient network failures so reruns do not fail early before deployment steps. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
39
.github/workflows/docker-build-deploy.yml
vendored
39
.github/workflows/docker-build-deploy.yml
vendored
@@ -223,8 +223,31 @@ jobs:
|
||||
|
||||
- name: Add server to known hosts
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p ~/.ssh
|
||||
ssh-keyscan -H -p "${SSH_PORT:-22}" "${SSH_HOST}" >> ~/.ssh/known_hosts
|
||||
touch ~/.ssh/known_hosts
|
||||
|
||||
KEYSCAN_OK=0
|
||||
for i in 1 2 3; do
|
||||
echo "ssh-keyscan attempt ${i}/3: ${SSH_HOST}:${SSH_PORT:-22}"
|
||||
if ssh-keyscan -T 10 -H -p "${SSH_PORT:-22}" "${SSH_HOST}" >> ~/.ssh/known_hosts 2>/tmp/ssh-keyscan.err; then
|
||||
KEYSCAN_OK=1
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$KEYSCAN_OK" -eq 1 ]; then
|
||||
echo "SSH_COMMON_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
|
||||
echo "--- ssh-keyscan stderr ---"
|
||||
cat /tmp/ssh-keyscan.err || true
|
||||
echo "--------------------------"
|
||||
fi
|
||||
echo "SSH_COMMON_OPTS=-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
- name: Prepare remote candidate release
|
||||
env:
|
||||
@@ -238,10 +261,10 @@ jobs:
|
||||
echo "镜像标签: $IMAGE_TAG"
|
||||
echo "部署目录: $COMPOSE_DIR/api"
|
||||
|
||||
echo "$ALIYUN_CR_PASSWORD" | ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" \
|
||||
echo "$ALIYUN_CR_PASSWORD" | ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" \
|
||||
"docker login $REGISTRY --username=$ALIYUN_CR_USERNAME --password-stdin"
|
||||
|
||||
ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
set -euo pipefail
|
||||
mkdir -p '$COMPOSE_DIR/api'
|
||||
mkdir -p '$COMPOSE_DIR/api/backups'
|
||||
@@ -272,10 +295,10 @@ jobs:
|
||||
fi
|
||||
|
||||
echo "上传候选 compose 与环境文件..."
|
||||
scp -P "$SSH_PORT" ./api/docker-compose.yml "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/docker-compose.candidate.yml"
|
||||
scp -P "$SSH_PORT" "$ENV_SRC" "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/.env.candidate"
|
||||
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 -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
set -euo pipefail
|
||||
cd '$COMPOSE_DIR/api'
|
||||
echo '拉取候选镜像: $IMAGE_TAG'
|
||||
@@ -291,7 +314,7 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "切换线上版本,容器启动时将自动执行 Alembic..."
|
||||
ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
set -euo pipefail
|
||||
cd '$COMPOSE_DIR/api'
|
||||
if [ -f '$COMPOSE_FILE' ]; then
|
||||
@@ -325,7 +348,7 @@ jobs:
|
||||
- name: Verify deployment
|
||||
run: |
|
||||
echo "验证部署状态..."
|
||||
ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" "
|
||||
set -euo pipefail
|
||||
cd '$COMPOSE_DIR/api'
|
||||
docker compose ps
|
||||
|
||||
Reference in New Issue
Block a user