caterium-app/ops/timeweb/caterium-production-sync.sh
pavlov346346 66d4414634 Ops: retarget Timeweb auto-deploy to app.caterium.ru, not the apex domain
caterium.ru and app.caterium.ru are separate Timeweb sites with separate
document roots. The apex domain's root is reserved for an unrelated future
site, so auto-detection must never be able to land there. Drop the generic
$HOME/public_html and unverified app.caterium.ru/public_html guesses in
favor of the confirmed real path ($HOME/caterium-app/public_html), and
require CATERIUM_WEB_ROOT explicitly in the documented cron command.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 20:39:16 +03:00

110 lines
3.0 KiB
Bash

#!/bin/sh
set -eu
REPO_URL="${CATERIUM_REPO_URL:-git@github.com:pavlov346346-source/caterium-app.git}"
BRANCH="${CATERIUM_BRANCH:-production}"
STATE_DIR="${CATERIUM_STATE_DIR:-$HOME/.caterium-deploy}"
REPO_DIR="${CATERIUM_REPO_DIR:-$STATE_DIR/repo}"
BACKUP_DIR="${CATERIUM_BACKUP_DIR:-$STATE_DIR/backups}"
LOCK_DIR="$STATE_DIR/lock"
log() {
printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
fail() {
log "ERROR: $*" >&2
exit 1
}
find_web_root() {
if [ -n "${CATERIUM_WEB_ROOT:-}" ]; then
printf '%s\n' "$CATERIUM_WEB_ROOT"
return 0
fi
for candidate in \
"$HOME/caterium-app/public_html"
do
if [ -d "$candidate" ] && [ -f "$candidate/index.html" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
command -v git >/dev/null 2>&1 || fail "git is not available"
command -v rsync >/dev/null 2>&1 || fail "rsync is not available"
command -v tar >/dev/null 2>&1 || fail "tar is not available"
mkdir -p "$STATE_DIR" "$BACKUP_DIR"
if ! mkdir "$LOCK_DIR" 2>/dev/null; then
if [ -f "$LOCK_DIR/pid" ]; then
old_pid=$(cat "$LOCK_DIR/pid" 2>/dev/null || true)
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
log "Another deployment is running; skip"
exit 0
fi
fi
rm -rf "$LOCK_DIR"
mkdir "$LOCK_DIR" 2>/dev/null || {
log "Could not acquire deployment lock; skip"
exit 0
}
fi
printf '%s\n' "$$" > "$LOCK_DIR/pid"
cleanup_lock() {
rm -rf "$LOCK_DIR"
}
trap cleanup_lock 0 HUP INT TERM
WEB_ROOT=$(find_web_root) || fail "web root not found; set CATERIUM_WEB_ROOT"
[ -d "$WEB_ROOT" ] || fail "web root does not exist: $WEB_ROOT"
if [ ! -d "$REPO_DIR/.git" ]; then
log "Initial clone of $BRANCH"
rm -rf "$REPO_DIR"
git clone --quiet --single-branch --branch "$BRANCH" "$REPO_URL" "$REPO_DIR" \
|| fail "initial Git clone failed; verify GitHub SSH key access"
fi
cd "$REPO_DIR"
log "Fetching $BRANCH"
git fetch --quiet origin "$BRANCH" || fail "git fetch failed"
NEW_SHA=$(git rev-parse FETCH_HEAD)
OLD_SHA=$(cat "$WEB_ROOT/.caterium-release" 2>/dev/null || true)
if [ "$NEW_SHA" = "$OLD_SHA" ]; then
log "Already current: $NEW_SHA"
exit 0
fi
git reset --quiet --hard "$NEW_SHA" || fail "could not switch deploy checkout"
[ -s "$REPO_DIR/public/index.html" ] || fail "release validation failed: public/index.html is missing or empty"
STAMP=$(date '+%Y%m%d-%H%M%S')
BACKUP_FILE="$BACKUP_DIR/${STAMP}-${OLD_SHA:-pre-marker}.tgz"
log "Backing up current site"
tar -czf "$BACKUP_FILE" -C "$WEB_ROOT" . || fail "backup failed; live files left unchanged"
log "Deploying $NEW_SHA to $WEB_ROOT"
rsync -a --delete-delay \
--exclude '.well-known/' \
--exclude '.caterium-release' \
"$REPO_DIR/public/" "$WEB_ROOT/" \
|| fail "rsync failed"
printf '%s\n' "$NEW_SHA" > "$WEB_ROOT/.caterium-release"
# Keep only the four newest rollback archives.
set +e
ls -1t "$BACKUP_DIR"/*.tgz 2>/dev/null | awk 'NR > 4' | while IFS= read -r old_backup; do
rm -f "$old_backup"
done
set -e
log "Deployment complete: $NEW_SHA"