refactor: switch from FTPS/lftp to rsync for deployment

Replace the FTPS-based deployment approach with rsync over SSH for more
reliable and efficient mirroring of the Hugo site. This change addresses
issues with the previous approach and provides true mirror behavior.

Key changes:
- Replace lftp with rsync for file synchronization
- Add --delete flag for true mirror behavior (removes stale remote files)
- Simplify authentication to use SSH keys only (no password needed)
- Update all documentation and OpenSpec artifacts
- Add .envrc to gitignore for direnv users

Environment variables:
- SSH_USER: SSH username (required)
- SSH_HOST: server hostname (required)
- SSH_PORT: SSH port (optional, defaults to 22)
- REMOTE_ROOT: remote directory path (optional, defaults to /httpsdocs)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-28 16:02:35 +01:00
co-authored by Claude
parent acdce1d15e
commit fcb82acc6f
6 changed files with 193 additions and 150 deletions
+46 -51
View File
@@ -1,24 +1,26 @@
#!/bin/bash
#
# FTPS Deployment Script for markusgraf.ch
# Rsync Deployment Script for markusgraf.ch
#
# This script deploys the Hugo-built static site to the production server
# via FTPS (FTP over SSL/TLS).
# via rsync over SSH, mirroring the content (including deletions).
#
# Prerequisites:
# - Hugo site must be built (public/ directory exists)
# - lftp must be installed
# - FTPS_PASSWORD environment variable must be set
# - SSH access to the server must be configured
# - SSH_USER, SSH_HOST environment variables must be set
#
# Usage:
# export FTPS_PASSWORD='your-password'
# export SSH_USER='your-username'
# export SSH_HOST='your-server.com'
# export SSH_PORT='22' # optional, defaults to 22
# export REMOTE_ROOT='/httpsdocs' # optional, defaults to /httpsdocs
# ./scripts/deploy.sh
#
# Server Details:
# - Server: www.markusgraf.ch
# - Username: gurix
# - Target Directory: httpsdocs/
# - Default Target Directory: /httpsdocs
# - Default Port: 22
# - Source Directory: public/
#
@@ -32,8 +34,8 @@ YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
FTPS_SERVER="www.markusgraf.ch"
TARGET_DIR="httpsdocs"
SSH_PORT="${SSH_PORT:-22}"
REMOTE_ROOT="${REMOTE_ROOT:-/httpsdocs}"
SOURCE_DIR="public"
#
@@ -80,71 +82,64 @@ check_prerequisites() {
error "Directory '$SOURCE_DIR' is empty. Please run 'hugo build' first."
fi
# Check if lftp is installed
if ! command -v lftp &> /dev/null; then
error "lftp is not installed. Please install it first:
Ubuntu/Debian: sudo apt-get install lftp
macOS: brew install lftp
Fedora: sudo dnf install lftp"
# Check if rsync is installed
if ! command -v rsync &> /dev/null; then
error "rsync is not installed. Please install rsync:
Ubuntu/Debian: sudo apt-get install rsync
macOS: rsync is pre-installed
Fedora: sudo dnf install rsync"
fi
# Check if FTPS_PASSWORD is set
if [ -z "${FTPS_PASSWORD:-}" ]; then
error "FTPS_PASSWORD environment variable is not set.
# Check if SSH_USER is set
if [ -z "${SSH_USER:-}" ]; then
error "SSH_USER environment variable is not set.
Please set it before running this script:
export FTPS_PASSWORD='your-password'"
export SSH_USER='your-username'"
fi
# Check if FTPS_USER is set
if [ -z "${FTPS_USER:-}" ]; then
error "FTPS_USER environment variable is not set.
# Check if SSH_HOST is set
if [ -z "${SSH_HOST:-}" ]; then
error "SSH_HOST environment variable is not set.
Please set it before running this script:
export FTPS_USER='user'"
export SSH_HOST='your-server.com'"
fi
success "All prerequisites met."
}
#
# Deploy site to server via FTPS
# Deploy site to server via rsync
#
deploy() {
info "Starting deployment to $FTPS_SERVER..."
info "Connecting as user: $FTPS_USER"
info "Uploading from: $SOURCE_DIR/"
info "Target directory: $TARGET_DIR/"
info "Starting deployment to $SSH_HOST..."
info "Connecting as user: $SSH_USER"
info "Port: $SSH_PORT"
info "Syncing from: $SOURCE_DIR/"
info "Target directory: $REMOTE_ROOT/"
# Use lftp to upload files via FTPS
# Note: Password is passed via environment variable to avoid exposure in process list
lftp -e "
set ftps:initial-prot '';
set ftp:ssl-force true;
set ftp:ssl-protect-data true;
set ssl:verify-certificate no;
set net:timeout 30;
set net:max-retries 3;
set net:reconnect-interval-base 5;
open ftps://$FTPS_USER:$FTPS_PASSWORD@$FTPS_SERVER;
cd $TARGET_DIR || mkdir -p $TARGET_DIR;
lcd $SOURCE_DIR;
mirror --reverse --delete --verbose --parallel=3;
bye
"
# Use rsync to mirror the content
# -a: archive mode (preserves permissions, timestamps, etc.)
# -v: verbose output
# -z: compress data during transfer
# --delete: delete files on remote that don't exist locally (mirror behavior)
# -e: specify SSH with custom port
rsync -avz --delete -e "ssh -p $SSH_PORT" "$SOURCE_DIR/" "$SSH_USER@$SSH_HOST:$REMOTE_ROOT/"
local exit_code=$?
if [ $exit_code -eq 0 ]; then
success "Deployment completed successfully!"
info "Your site is now live at https://markusgraf.ch"
info "Files have been synced to $SSH_HOST:$REMOTE_ROOT"
return 0
else
error "Deployment failed with exit code $exit_code.
Troubleshooting:
- Verify your password is correct
- Check network connectivity to $FTPS_SERVER
- Ensure the target directory '$TARGET_DIR' exists on the server
- Check server logs for additional details"
- Verify SSH credentials and key-based authentication is set up
- Check network connectivity to $SSH_HOST
- Ensure the target directory '$REMOTE_ROOT' exists on the server
- Verify SSH_USER has write permissions to $REMOTE_ROOT
- Try connecting manually: ssh -p $SSH_PORT $SSH_USER@$SSH_HOST"
fi
}
@@ -152,7 +147,7 @@ Troubleshooting:
# Main execution
#
main() {
info "=== FTPS Deployment Script ==="
info "=== Rsync Deployment Script ==="
info ""
check_prerequisites