deploy: add hatch.surf static site deployment
- Extended GitHub Actions workflow to deploy to server via rsync - Fixed favicon reference in index.html (favicon.png → favicon-48.png) - Added deploy-site.sh script for manual deployments - Added deploy-homepage.md documentation Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
12775f836c
commit
25cb834376
33
.github/workflows/deploy-site.yml
vendored
33
.github/workflows/deploy-site.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Deploy static site to GitHub Pages
|
name: Deploy static site
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -20,7 +20,8 @@ concurrency:
|
|||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy-github-pages:
|
||||||
|
name: Deploy to GitHub Pages
|
||||||
environment:
|
environment:
|
||||||
name: github-pages
|
name: github-pages
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
@ -40,4 +41,30 @@ jobs:
|
|||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v4
|
uses: actions/deploy-pages@v4
|
||||||
|
|
||||||
|
deploy-server:
|
||||||
|
name: Deploy to hatch.surf server
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Deploy via rsync
|
||||||
|
uses: burnett01/rsync-deployments@7.0.1
|
||||||
|
with:
|
||||||
|
switches: -avz --delete
|
||||||
|
path: site/
|
||||||
|
remote_path: /var/www/hatch.surf/
|
||||||
|
remote_host: ${{ secrets.DEPLOY_HOST }}
|
||||||
|
remote_user: ${{ secrets.DEPLOY_USER }}
|
||||||
|
remote_key: ${{ secrets.DEPLOY_KEY }}
|
||||||
|
|
||||||
|
- name: Reload nginx
|
||||||
|
uses: appleboy/ssh-action@v1
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.DEPLOY_HOST }}
|
||||||
|
username: ${{ secrets.DEPLOY_USER }}
|
||||||
|
key: ${{ secrets.DEPLOY_KEY }}
|
||||||
|
script: |
|
||||||
|
nginx -t && systemctl reload nginx
|
||||||
|
|||||||
170
docs/engineering/deploy-homepage.md
Normal file
170
docs/engineering/deploy-homepage.md
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
# Deploying the Hatch Homepage
|
||||||
|
|
||||||
|
This document describes how the Hatch static homepage is deployed to hatch.surf.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The homepage is deployed to two locations:
|
||||||
|
|
||||||
|
1. **GitHub Pages** - Serves as a fallback and for GitHub-based discovery
|
||||||
|
2. **hatch.surf server** - Primary deployment at https://hatch.surf
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
site/
|
||||||
|
├── index.html # Main homepage
|
||||||
|
├── style.css # Stylesheet
|
||||||
|
├── brand/ # Logo and favicon assets
|
||||||
|
│ ├── favicon/
|
||||||
|
│ └── og/
|
||||||
|
└── blog/ # Blog directory (placeholder)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Server Setup
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Server: 46.250.250.48 (hatch.surf)
|
||||||
|
- nginx installed and configured
|
||||||
|
- Let's Encrypt certificate for hatch.surf
|
||||||
|
- SSH access for deployment
|
||||||
|
|
||||||
|
### Nginx Configuration
|
||||||
|
|
||||||
|
The nginx server block is located at:
|
||||||
|
- `/etc/nginx/sites-available/hatch.surf.conf`
|
||||||
|
- Symlinked to `/etc/nginx/sites-enabled/hatch.surf.conf`
|
||||||
|
|
||||||
|
Configuration highlights:
|
||||||
|
- HTTP → HTTPS redirect
|
||||||
|
- SSL with Let's Encrypt certificate
|
||||||
|
- Security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy)
|
||||||
|
- Gzip compression
|
||||||
|
- Static asset caching (30 days)
|
||||||
|
|
||||||
|
### SSL Certificate
|
||||||
|
|
||||||
|
- Certificate managed by Let's Encrypt
|
||||||
|
- Auto-renewal via certbot
|
||||||
|
- Expiry: September 22, 2026
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Automated (GitHub Actions)
|
||||||
|
|
||||||
|
When changes are pushed to `main` branch affecting `site/` directory:
|
||||||
|
|
||||||
|
1. **GitHub Pages** - Deployed automatically via GitHub Actions
|
||||||
|
2. **Server** - Deployed via rsync to `/var/www/hatch.surf/`
|
||||||
|
|
||||||
|
Required GitHub secrets:
|
||||||
|
- `DEPLOY_HOST` - Server IP (46.250.250.48)
|
||||||
|
- `DEPLOY_USER` - SSH username (root)
|
||||||
|
- `DEPLOY_KEY` - SSH private key (base64 encoded)
|
||||||
|
|
||||||
|
### Manual Deployment
|
||||||
|
|
||||||
|
Use the deployment script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Dry run
|
||||||
|
./scripts/deploy-site.sh --dry-run
|
||||||
|
|
||||||
|
# Deploy
|
||||||
|
DEPLOY_HOST=46.250.250.48 \
|
||||||
|
DEPLOY_USER=root \
|
||||||
|
DEPLOY_KEY=$(cat ~/.ssh/id_rsa | base64) \
|
||||||
|
./scripts/deploy-site.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Direct rsync
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -avz --delete site/ root@46.250.250.48:/var/www/hatch.surf/
|
||||||
|
ssh root@46.250.250.48 "nginx -t && systemctl reload nginx"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
### Check Site Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# HTTP redirect
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" http://hatch.surf/
|
||||||
|
|
||||||
|
# HTTPS site
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" https://hatch.surf/
|
||||||
|
|
||||||
|
# SSL certificate
|
||||||
|
curl -v https://hatch.surf/ 2>&1 | grep -E "expire|issuer|subject"
|
||||||
|
|
||||||
|
# Static assets
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" https://hatch.surf/style.css
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" https://hatch.surf/brand/og/default.png
|
||||||
|
```
|
||||||
|
|
||||||
|
### Browser Verification
|
||||||
|
|
||||||
|
1. Visit https://hatch.surf
|
||||||
|
2. Verify no browser warnings (SSL valid)
|
||||||
|
3. Check that all assets load (CSS, images)
|
||||||
|
4. Test responsive design
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### SSL Certificate Issues
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check certificate status
|
||||||
|
sudo certbot certificates
|
||||||
|
|
||||||
|
# Renew certificate manually
|
||||||
|
sudo certbot renew --cert-name hatch.surf
|
||||||
|
|
||||||
|
# Test nginx config
|
||||||
|
sudo nginx -t
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deployment Failures
|
||||||
|
|
||||||
|
1. Check GitHub Actions logs
|
||||||
|
2. Verify SSH access: `ssh root@46.250.250.48`
|
||||||
|
3. Check nginx status: `sudo systemctl status nginx`
|
||||||
|
4. Check nginx logs: `sudo tail -f /var/log/nginx/error.log`
|
||||||
|
|
||||||
|
### Missing Assets
|
||||||
|
|
||||||
|
1. Verify files exist on server: `ls -la /var/www/hatch.surf/brand/`
|
||||||
|
2. Check nginx access logs: `sudo tail -f /var/log/nginx/access.log`
|
||||||
|
3. Ensure proper file permissions: `chown -R www-data:www-data /var/www/hatch.surf`
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
### Updating Content
|
||||||
|
|
||||||
|
1. Edit files in `site/` directory
|
||||||
|
2. Commit and push to `main` branch
|
||||||
|
3. GitHub Actions will auto-deploy to both locations
|
||||||
|
|
||||||
|
### SSL Renewal
|
||||||
|
|
||||||
|
Certbot is configured to auto-renew. To check renewal status:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo certbot renew --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
|
||||||
|
The site is version-controlled in Git. For server backups:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup nginx config
|
||||||
|
sudo tar -czf nginx-hatch-backup.tar.gz /etc/nginx/sites-available/hatch.surf.conf /etc/letsencrypt/live/hatch.surf/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Issues
|
||||||
|
|
||||||
|
- [ELF-192](/ELF/issues/ELF-192) - Build homepage and deploy it on hatch.surf
|
||||||
|
- [ELF-171](/ELF/issues/ELF-171) - Server setup (nginx, SSL)
|
||||||
92
scripts/deploy-site.sh
Executable file
92
scripts/deploy-site.sh
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Deploy static site to hatch.surf server
|
||||||
|
# Usage: ./scripts/deploy-site.sh [--dry-run]
|
||||||
|
#
|
||||||
|
# Environment variables required:
|
||||||
|
# DEPLOY_HOST - SSH host (e.g., 46.250.250.48)
|
||||||
|
# DEPLOY_USER - SSH user (e.g., root)
|
||||||
|
# DEPLOY_KEY - SSH private key (base64 encoded, optional if using ssh-agent)
|
||||||
|
#
|
||||||
|
# The script deploys the contents of the site/ directory to /var/www/hatch.surf
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
SITE_DIR="$REPO_ROOT/site"
|
||||||
|
REMOTE_DIR="/var/www/hatch.surf"
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
DEPLOY_HOST="${DEPLOY_HOST:-46.250.250.48}"
|
||||||
|
DEPLOY_USER="${DEPLOY_USER:-root}"
|
||||||
|
DEPLOY_KEY="${DEPLOY_KEY:-}"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
DRY_RUN=false
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $arg in
|
||||||
|
--dry-run)
|
||||||
|
DRY_RUN=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo -e "${GREEN}✓${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}⚠${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}✗${NC} $1" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate
|
||||||
|
if [ ! -d "$SITE_DIR" ]; then
|
||||||
|
error "Site directory not found: $SITE_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$SITE_DIR/index.html" ]; then
|
||||||
|
error "index.html not found in $SITE_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Setup SSH key if provided
|
||||||
|
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=10"
|
||||||
|
if [ -n "$DEPLOY_KEY" ]; then
|
||||||
|
SSH_KEY_FILE=$(mktemp)
|
||||||
|
echo "$DEPLOY_KEY" | base64 -d > "$SSH_KEY_FILE"
|
||||||
|
chmod 600 "$SSH_KEY_FILE"
|
||||||
|
SSH_OPTS="$SSH_OPTS -i $SSH_KEY_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Deploy
|
||||||
|
DEPLOY_TARGET="${DEPLOY_USER}@${DEPLOY_HOST}"
|
||||||
|
|
||||||
|
if [ "$DRY_RUN" = true ]; then
|
||||||
|
warn "Dry run - would deploy to $DEPLOY_TARGET:$REMOTE_DIR"
|
||||||
|
rsync -avz --delete --dry-run $SSH_OPTS "$SITE_DIR/" "$DEPLOY_TARGET:$REMOTE_DIR/"
|
||||||
|
else
|
||||||
|
log "Deploying to $DEPLOY_TARGET:$REMOTE_DIR"
|
||||||
|
rsync -avz --delete $SSH_OPTS "$SITE_DIR/" "$DEPLOY_TARGET:$REMOTE_DIR/"
|
||||||
|
|
||||||
|
# Reload nginx
|
||||||
|
log "Reloading nginx..."
|
||||||
|
ssh $SSH_OPTS "$DEPLOY_TARGET" "nginx -t && systemctl reload nginx"
|
||||||
|
|
||||||
|
log "Deployment complete!"
|
||||||
|
log "Site live at https://hatch.surf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Cleanup SSH key if created
|
||||||
|
if [ -n "$SSH_KEY_FILE" ]; then
|
||||||
|
rm -f "$SSH_KEY_FILE"
|
||||||
|
fi
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<meta name="twitter:image" content="/brand/og/default.png">
|
<meta name="twitter:image" content="/brand/og/default.png">
|
||||||
|
|
||||||
<link rel="canonical" href="https://hatch.sh">
|
<link rel="canonical" href="https://hatch.sh">
|
||||||
<link rel="icon" type="image/png" href="/brand/favicon/favicon.png">
|
<link rel="icon" type="image/png" href="/brand/favicon/favicon-48.png">
|
||||||
<link rel="stylesheet" href="/style.css">
|
<link rel="stylesheet" href="/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user