Files
gurixandClaude fcb82acc6f 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>
2025-10-28 16:02:35 +01:00

220 lines
5.7 KiB
Markdown

# Deployment Guide
This guide explains how to deploy the Hugo-built static site to the production server via rsync over SSH, properly mirroring the content.
## Prerequisites
Before deploying, ensure you have:
1. **Built the site**: Run `hugo build` to generate the `public/` directory
2. **SSH access configured**: You need SSH access to your server with key-based authentication
3. **Rsync available**: The deployment script requires the `rsync` command-line tool
### Installing Rsync
Rsync is typically pre-installed on most systems, but if needed:
```bash
# Ubuntu/Debian
sudo apt-get install rsync
# macOS (usually pre-installed)
# No action needed, or: brew install rsync
# Fedora
sudo dnf install rsync
```
## Deployment Process
### 1. Build the Site
First, build the Hugo site:
```bash
hugo build
```
This generates the static files in the `public/` directory.
### 2. Set Environment Variables
Set the SSH connection details as environment variables:
```bash
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
```
**Important**: Ensure SSH key-based authentication is set up for password-less access.
### 3. Run the Deployment Script
Execute the deployment script:
```bash
./scripts/deploy.sh
```
The script will:
- Check that all prerequisites are met
- Connect to your server via rsync over SSH
- Sync all files from `public/` to the specified remote directory
- Delete remote files that don't exist locally (true mirror behavior)
- Display progress and completion status
### Complete Example
Here's the full workflow:
```bash
# Build the site
hugo build
# Set connection details (only needed once per session)
export SSH_USER='your-username'
export SSH_HOST='your-server.com'
export SSH_PORT='22' # Optional
export REMOTE_ROOT='/httpsdocs' # Optional
# Deploy
./scripts/deploy.sh
```
## Server Configuration
The deployment script uses the following configuration:
- **Protocol**: rsync over SSH
- **Default Port**: 22 (configurable via SSH_PORT)
- **Default Target Directory**: /httpsdocs (configurable via REMOTE_ROOT)
- **Source Directory**: public/
- **Sync Behavior**: Mirror mode with `--delete` flag (removes remote files not present locally)
## Security Notes
### SSH Key-Based Authentication
The deployment script uses SSH/SCP, which supports key-based authentication:
- **Set up SSH keys**: Generate an SSH key pair and add your public key to the server's `~/.ssh/authorized_keys`
- **Test SSH access**: Verify you can connect without a password: `ssh -p 22 user@server`
- **No password required**: SCP will use your SSH keys automatically
- **Never** commit private keys to version control
### Optional: Using .env Files
For convenience, you can create a `.env` file (which is ignored by git):
```bash
# .env
export SSH_USER='your-username'
export SSH_HOST='your-server.com'
export SSH_PORT='22'
export REMOTE_ROOT='/httpsdocs'
```
Then source it before deployment:
```bash
source .env
./scripts/deploy.sh
```
## Troubleshooting
### Error: "Directory 'public' does not exist"
**Cause**: The Hugo site hasn't been built yet.
**Solution**: Run `hugo build` before deploying.
### Error: "rsync is not installed"
**Cause**: The `rsync` tool is not available on your system.
**Solution**: Install rsync using the instructions above.
### Error: "SSH_USER environment variable is not set"
**Cause**: Required environment variables haven't been set.
**Solution**: Set the required variables:
```bash
export SSH_USER='your-username'
export SSH_HOST='your-server.com'
```
### SSH Connection Failures
**Cause**: SSH authentication issues or network problems.
**Solutions**:
- Verify you can connect manually: `ssh -p 22 user@server`
- Check that your SSH key is added to the server's `~/.ssh/authorized_keys`
- Ensure your internet connection is working
- Verify the server is accessible
- Check firewall settings aren't blocking SSH (default port 22)
### Permission Denied on Remote Directory
**Cause**: User doesn't have write permissions to the target directory.
**Solution**:
- Verify the REMOTE_ROOT directory exists on the server
- Ensure your SSH user has write permissions to that directory
- Contact your server administrator if needed
## Advanced Usage
### Testing SSH Connection
To test your SSH connection before deploying:
```bash
# Test basic SSH connection
ssh -p "${SSH_PORT:-22}" "$SSH_USER@$SSH_HOST"
# Test that you can write to the target directory
ssh -p "${SSH_PORT:-22}" "$SSH_USER@$SSH_HOST" "touch ${REMOTE_ROOT:-/httpsdocs}/test.txt && rm ${REMOTE_ROOT:-/httpsdocs}/test.txt"
```
### Deployment from CI/CD
For automated deployments from CI/CD pipelines:
1. Set up SSH key-based authentication for your CI/CD runner
2. Store `SSH_USER` and `SSH_HOST` as environment variables or secrets
3. Ensure the CI/CD environment has `rsync` installed
4. Run the deployment script after successful builds
Example GitHub Actions workflow snippet:
```yaml
- name: Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to server
env:
SSH_USER: ${{ secrets.SSH_USER }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_PORT: ${{ secrets.SSH_PORT }}
REMOTE_ROOT: ${{ secrets.REMOTE_ROOT }}
run: ./scripts/deploy.sh
```
## Support
If you encounter issues not covered in this guide:
1. Test SSH connectivity manually: `ssh user@server`
2. Check server logs for authentication or permission issues
3. Verify the target directory exists and has correct permissions
4. Contact your hosting provider for server-side issues