thermograph/.forgejo/workflows/ops-cron.yml

67 lines
2.7 KiB
YAML

name: Ops cron (backup + IndexNow)
# Scheduled operational jobs that don't belong in the app's own worker-tier
# scheduler (notifications/scheduler.py, Track A chunk 5) because they're
# infra/ops concerns rather than app-domain background work -- see the job
# classification table in
# docs/architecture/repo-topology-and-infrastructure.md §7.
#
# Both jobs SSH into the prod host and run inside the already-running compose
# stack (docker compose exec), the same way deploy.sh already runs its own
# post-deploy IndexNow ping -- no new network exposure, no separate dependency
# install. Runs on the `docker` label (the always-on Swarm-hosted runner
# deploy/forgejo/ stood up) and reuses the same SSH secrets deploy.yml already
# has (SSH_HOST/SSH_USER/SSH_KEY/SSH_PORT) -- inherits, and will automatically
# benefit from a fix to, deploy.yml's own flagged branch/host mismatch (that
# workflow's header comment: it still targets `main`, while
# terraform.tfvars.example names prod's branch `release`).
on:
schedule:
# 03:00 UTC daily -- a low-traffic window for both jobs.
- cron: '0 3 * * *'
workflow_dispatch: {}
jobs:
backup:
name: pg_dump backup
runs-on: docker
steps:
- name: Dump the prod database over SSH
uses: https://github.com/appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
set -euo pipefail
cd /opt/thermograph
backup_dir="$HOME/thermograph-backups"
mkdir -p "$backup_dir"
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
out="$backup_dir/thermograph-$stamp.dump"
docker compose exec -T db pg_dump -U thermograph -d thermograph \
--format=custom > "$out"
echo "wrote $out ($(du -h "$out" | cut -f1))"
# The dumps are the disaster-recovery copy, not a versioned
# archive -- keep the last 14 days and let the rest age out.
find "$backup_dir" -name 'thermograph-*.dump' -mtime +14 -delete
indexnow:
name: IndexNow ping
runs-on: docker
steps:
- name: Ping IndexNow if the URL set changed
uses: https://github.com/appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
set -euo pipefail
cd /opt/thermograph
set -a; . /etc/thermograph.env 2>/dev/null || true; set +a
docker compose exec -T backend python indexnow.py --if-changed \
"${THERMOGRAPH_BASE_URL:-https://thermograph.org}"