# Scheduled ModelForge backups. # # Deployment infrastructure owns the schedule, not an operator and not an interactive session: # # docker compose -p modelforge --env-file .env \ # -f docker-compose.yml -f docker-compose.backup.yml up -d backup-scheduler # # The scheduler calls the same operator-authenticated recovery API a human would: create, verify, # then apply retention. It holds no database credential, no encryption key and no filesystem access # to the backup root — the control plane does all of that behind its own guards. # # An Unraid User Script or a systemd timer invoking scripts/modelforge_scheduled_backup.sh directly # is equally supported; this service exists so a Compose-only deployment is still protected. services: backup-scheduler: image: curlimages/curl:8.11.1@sha256:c1fe1679c34d9784c1b0d1e5f62ac0a79fca01fb6377cdd33e90473c6f9f9a69 entrypoint: ["/bin/sh"] command: - "-c" - | set -eu while true; do sh /opt/modelforge/modelforge_scheduled_backup.sh || \ echo "scheduled backup failed; BACKUP_FAILED and BACKUP_STALE will report it" sleep "${MODELFORGE_BACKUP_INTERVAL_SECONDS:-86400}" done environment: MODELFORGE_BASE_URL: ${MODELFORGE_BACKUP_BASE_URL:-http://api:8000} MODELFORGE_OPERATOR_API_KEY: ${MODELFORGE_OPERATOR_API_KEY:-} MODELFORGE_BACKUP_ID_PREFIX: ${MODELFORGE_BACKUP_ID_PREFIX:-scheduled} MODELFORGE_BACKUP_INTERVAL_SECONDS: ${MODELFORGE_BACKUP_INTERVAL_SECONDS:-86400} volumes: - ./scripts/modelforge_scheduled_backup.sh:/opt/modelforge/modelforge_scheduled_backup.sh:ro depends_on: api: condition: service_healthy read_only: true cap_drop: - ALL security_opt: - no-new-privileges:true restart: unless-stopped