ci(deploy): revert to rsync via SSH port 222 (Hetzner shell port)
All checks were successful
ci / build-test (push) Successful in 3m57s
All checks were successful
ci / build-test (push) Successful in 3m57s
Hetzner Webhosting exposes SSH on TWO ports:
port 22 — SFTP only, refuses remote command exec
port 222 — full SSH with shell, supports rsync
Previous deploys hit "exec request failed on channel 0" because we
were using port 22. Switch back from lftp to plain rsync, but route
it through port 222 with --rsync-path=/usr/bin/rsync (Hetzner's
locked-down PATH doesn't include rsync by default) and BatchMode=yes
to disable interactive prompts.
Mirrors the working local command:
rsync -avz --rsync-path=/usr/bin/rsync \
-e "ssh -p 222 -i ~/.ssh/id_ed25519_gitea -o BatchMode=yes" \
./ apibny@www691.your-server.de:/usr/www/users/apibny/www.cameleer.io
Keeps host-key pinning (StrictHostKeyChecking + UserKnownHostsFile)
which the local command omits because the user's personal known_hosts
already trusts the host.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -96,43 +96,33 @@ jobs:
|
|||||||
chmod 600 ~/.ssh/id_ed25519
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
printf '%s\n' "$SFTP_KNOWN_HOSTS" > ~/.ssh/known_hosts
|
printf '%s\n' "$SFTP_KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||||
chmod 644 ~/.ssh/known_hosts
|
chmod 644 ~/.ssh/known_hosts
|
||||||
# Hetzner Webhosting accounts are SFTP-only — they accept SSH for file
|
# Ensure rsync + openssh are present even on a minimal runner image.
|
||||||
# transfer but refuse remote command exec ("exec request failed on
|
if ! command -v rsync >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then
|
||||||
# channel 0"). rsync over SSH needs to spawn a remote rsync binary,
|
|
||||||
# so it cannot work here. Use lftp's mirror instead, which speaks
|
|
||||||
# SFTP end-to-end with the same key + known_hosts pinning.
|
|
||||||
if ! command -v lftp >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then
|
|
||||||
if command -v sudo >/dev/null 2>&1; then SUDO=sudo; else SUDO=; fi
|
if command -v sudo >/dev/null 2>&1; then SUDO=sudo; else SUDO=; fi
|
||||||
$SUDO apt-get update -qq
|
$SUDO apt-get update -qq
|
||||||
$SUDO apt-get install -y --no-install-recommends lftp openssh-client
|
$SUDO apt-get install -y --no-install-recommends rsync openssh-client
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Deploy via lftp (mirror over SFTP)
|
- name: Deploy via rsync
|
||||||
env:
|
env:
|
||||||
SFTP_USER: ${{ secrets.SFTP_USER }}
|
SFTP_USER: ${{ secrets.SFTP_USER }}
|
||||||
SFTP_HOST: ${{ secrets.SFTP_HOST }}
|
SFTP_HOST: ${{ secrets.SFTP_HOST }}
|
||||||
SFTP_PATH: ${{ secrets.SFTP_PATH }}
|
SFTP_PATH: ${{ secrets.SFTP_PATH }}
|
||||||
run: |
|
run: |
|
||||||
# Fail loudly if any secret is missing — otherwise mirror --delete
|
# Fail loudly if any secret is missing — otherwise rsync --delete
|
||||||
# could be directed at the SSH user's home root.
|
# could be directed at the SSH user's home root.
|
||||||
: "${SFTP_USER:?SFTP_USER secret must be set}"
|
: "${SFTP_USER:?SFTP_USER secret must be set}"
|
||||||
: "${SFTP_HOST:?SFTP_HOST secret must be set}"
|
: "${SFTP_HOST:?SFTP_HOST secret must be set}"
|
||||||
: "${SFTP_PATH:?SFTP_PATH secret must be set}"
|
: "${SFTP_PATH:?SFTP_PATH secret must be set}"
|
||||||
# `-u USER,` (with trailing comma = empty password) tells lftp not
|
# Hetzner Webhosting splits SSH into two ports:
|
||||||
# to prompt for a password; auth happens via the key passed to ssh
|
# port 22 — SFTP only, no remote command exec
|
||||||
# by sftp:connect-program. Heredoc body is unindented so lftp's
|
# port 222 — full SSH with shell exec (rsync needs this)
|
||||||
# parser doesn't mistake leading whitespace for a continuation.
|
# `--rsync-path=/usr/bin/rsync` tells the local rsync where to find
|
||||||
# `debug 3` prints the ssh command lftp invokes — useful if this
|
# the remote binary on Hetzner's locked-down PATH.
|
||||||
# ever breaks again.
|
# `BatchMode=yes` disables interactive prompts.
|
||||||
lftp <<LFTP
|
rsync -avz --delete --rsync-path=/usr/bin/rsync \
|
||||||
debug 3
|
-e "ssh -p 222 -i $HOME/.ssh/id_ed25519 -o BatchMode=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/known_hosts" \
|
||||||
set cmd:fail-exit yes
|
dist/ "$SFTP_USER@$SFTP_HOST:$SFTP_PATH/"
|
||||||
set net:max-retries 1
|
|
||||||
set sftp:connect-program 'ssh -a -x -i $HOME/.ssh/id_ed25519 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/known_hosts'
|
|
||||||
open -u $SFTP_USER, sftp://$SFTP_HOST
|
|
||||||
mirror --reverse --delete --verbose --parallel=4 dist/ $SFTP_PATH/
|
|
||||||
bye
|
|
||||||
LFTP
|
|
||||||
|
|
||||||
- name: Post-deploy smoke test
|
- name: Post-deploy smoke test
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
Reference in New Issue
Block a user