#!/usr/bin/env bash # 备份 sundynix-agentix 全部有状态数据(PG / Neo4j / Milvus / MinIO / NATS-JetStream)。 # 用法:scripts/backup.sh [输出目录] 默认 ./backups/<时间戳> # 建议 cron 每日跑,产物拷到异机。 set -euo pipefail COMPOSE="docker compose -f docker-compose.prod.yml" TS="$(date +%Y%m%d-%H%M%S)" OUT="${1:-./backups/$TS}" mkdir -p "$OUT" echo "[backup] → $OUT" # PostgreSQL:逻辑备份(可跨版本恢复)。 echo "[backup] postgres…" $COMPOSE exec -T postgres pg_dump -U sundynix sundynix | gzip > "$OUT/postgres.sql.gz" # Neo4j:在线 dump(社区版用 cypher-shell 导出关系;这里用 APOC/dump 兼容写法的简化版—— # 社区版无 neo4j-admin 在线 dump,改为停服卷拷或用 cypher 导出。此处导出全图为 cypher。) echo "[backup] neo4j…" $COMPOSE exec -T neo4j sh -lc 'command -v neo4j-admin >/dev/null 2>&1 && neo4j-admin database dump neo4j --to-stdout 2>/dev/null' \ > "$OUT/neo4j.dump" 2>/dev/null || echo "[backup] neo4j 在线 dump 不可用(社区版),改用卷快照见下" # 数据卷快照(Milvus / MinIO / Neo4j 兜底 / JetStream):用临时容器打 tar。 backup_volume () { # $1=卷名 $2=输出文件 local vol; vol="$($COMPOSE config --volumes | grep -E "^${1}\$" || true)" local full="$(docker volume ls --format '{{.Name}}' | grep -E "_${1}\$" | head -1)" [ -z "$full" ] && { echo "[backup] 卷 $1 未找到,跳过"; return; } echo "[backup] volume $full…" docker run --rm -v "$full":/data -v "$(cd "$OUT" && pwd)":/out alpine \ sh -c "cd /data && tar czf /out/$2 ." } backup_volume milvus_data milvus_data.tar.gz backup_volume minio_data minio_data.tar.gz backup_volume neo4j_data neo4j_data.tar.gz backup_volume nats_data nats_data.tar.gz echo "[backup] 完成。务必另存 .env(含 SUNDYNIX_SECRET_KEY,丢了模型密钥全废):cp .env $OUT/env.bak" echo "$OUT"