mirror of
https://gitverse.ru/kpa39l/gotosocial.git
synced 2026-09-29 01:50:08 +00:00
63 lines
2.5 KiB
Bash
Executable File
63 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================
|
|
# GoToSocial backup: SQLite consistent + медиа → backups/
|
|
# + копия на Яндекс.Диск (ротация 7 дней локально / 30 на ЯД)
|
|
#
|
|
# Топология: /opt/gotosocial/data → /gotosocial/storage (контейнер)
|
|
# data/sqlite.db + media лежат прямо в data/ (storage-маунт)
|
|
# SQLite: Backup API через python3 (sqlite3 CLI не установлен)
|
|
# Тихий: stdout пуст при успехе (для no_agent cron), не-ноль при ошибке
|
|
# =============================================================
|
|
set -euo pipefail
|
|
|
|
BASE_DIR="/opt/gotosocial"
|
|
DATA_DIR="${BASE_DIR}/data"
|
|
BACKUP_DIR="${BASE_DIR}/backups"
|
|
YANDEX_MOUNT="/mnt/yandex-disk"
|
|
YANDEX_DIR="${YANDEX_MOUNT}/backup/gotosocial-backups"
|
|
STAGE="${BACKUP_DIR}/stage"
|
|
TS="$(date +%Y%m%d_%H%M%S)"
|
|
|
|
mkdir -p "${BACKUP_DIR}"
|
|
rm -rf "${STAGE}" && mkdir -p "${STAGE}"
|
|
|
|
# --- Компактный снапшот БД через SQLite Backup API (online, без конфликтов) ---
|
|
python3 - "${DATA_DIR}/sqlite.db" "${STAGE}/sqlite.db" <<'PYEOF'
|
|
import sqlite3, sys
|
|
src, dst = sys.argv[1], sys.argv[2]
|
|
s = sqlite3.connect(src)
|
|
d = sqlite3.connect(dst)
|
|
with d:
|
|
s.backup(d)
|
|
d.close()
|
|
s.close()
|
|
PYEOF
|
|
|
|
# --- Медиа копируем в stage (без WAL/SHM, с сохранением структуры) ---
|
|
# Исключаем служебные sqlite-файлы из data/, чтобы не дублировать БД
|
|
(cd "${DATA_DIR}" && tar -cf - --exclude='sqlite.db*' .) | tar -xf - -C "${STAGE}"
|
|
|
|
# --- Итоговый архив: consistent db + медиа ---
|
|
ARCHIVE="${BACKUP_DIR}/gotosocial_${TS}.tar.gz"
|
|
tar -C "${STAGE}" -czf "${ARCHIVE}" .
|
|
|
|
# --- Архив секретов (.env) отдельно ---
|
|
ENV_ARCHIVE="${BACKUP_DIR}/gotosocial_env_${TS}.tar.gz"
|
|
tar -C "${BASE_DIR}" -czf "${ENV_ARCHIVE}" .env
|
|
|
|
# --- Копия на Яндекс.Диск ---
|
|
if ! mountpoint -q "${YANDEX_MOUNT}"; then
|
|
echo "ERROR: Яндекс.Диск не примонтирован (${YANDEX_MOUNT})" >&2
|
|
exit 1
|
|
fi
|
|
mkdir -p "${YANDEX_DIR}"
|
|
cp -p "${ARCHIVE}" "${ENV_ARCHIVE}" "${YANDEX_DIR}/"
|
|
|
|
# --- Ротация: локально 7 дней, ЯД 30 дней ---
|
|
find "${BACKUP_DIR}" -maxdepth 1 -type f -name 'gotosocial_*' -mtime +7 -delete
|
|
find "${YANDEX_DIR}" -maxdepth 1 -type f -name 'gotosocial_*' -mtime +30 -delete
|
|
|
|
rm -rf "${STAGE}"
|
|
|
|
# Успех — тихо (для no_agent cron)
|
|
exit 0 |