chore: STATUS.md обновлён (деплой завершён), backup.sh на SQLite Backup API

This commit is contained in:
estorozhenko
2026-09-06 19:43:05 +00:00
parent d9951b6048
commit 9f693c8f7b
2 changed files with 76 additions and 38 deletions
+43 -23
View File
@@ -1,34 +1,54 @@
# GoToSocial — Статус # GoToSocial — Статус
Обновлено: 2026-09-06 (сессия 2026-09-06_19xx) Обновлено: 2026-09-06 (поздний вечер, деплой завершён)
## Текущее состояние ## Текущее состояние
Проект развёртывания GoToSocial-ноды на social.dedinit.ru оформлен: создан каталог /opt/gotosocial, OpenSpec change deploy-gotosocial (валиден), все рабочие файлы (compose, config, .env, backup.sh, README) готовы и запушены в git. **Сервис ещё НЕ запущен** — это следующий шаг. DNS social.dedinit.ru → 87.242.100.206 (vps02) создан пользователем. GoToSocial **запущен и работает** на social.dedinit.ru: контейнер Up, HTTPS 200, админ создан.
Split-domain работает: аккаунты `@user@dedinit.ru`, хост social.dedinit.ru, apex-webfinger отдаёт JSON.
Ежедневный cron-бэкап (02:00) активен и проверен.
## Сделано ## Сделано
- 2026-09-06: исследование развёртывания GoToSocial (доки v0.22.1, split-domain, Docker) ### Запуск на bigbox (шаг 1)
- 2026-09-06: каталог /opt/gotosocial, OpenSpec init + change `deploy-gotosocial` (proposal/spec×2/design/tasks), `openspec validate` ✅ - 2026-09-06: тег образа `0.22.1` (не `v0.22.1` — оригинала не существует), порт `8082:8080`
- 2026-09-06: docker-compose.yml (v0.22.1, SQLite, порт 8080, volume ./data, net 172.29.0.0/16) (8080 на bigbox занят NetBox!), права `data/` → 1000:1000
- 2026-09-06: config.yaml (host=social.dedinit.ru, account-domain=dedinit.ru, SMTP Jino, metrics, log json) - 2026-09-06: конфиг через `GTS_*` env — docker-образ НЕ читает смонтированный config.yaml
- 2026-09-06: .env (SMTP-пароль; в git исключён), backup.sh (SQLite VACUUM INTO + медиа, ротация 7д/30д, ЯД), README.md, .gitignore (падал «host must be set»), .cache для Wazero
- 2026-09-06: git init + commit d385d8b - 2026-09-06: админ `estorozhenko` создан/confirmed/promoted; HTTPS LE на social.dedinit.ru ✅
- 2026-09-06: gitverse репо `kpa39l/gotosocial` создан (API, Bearer+Accept object+json), main запушен
- 2026-09-06: gitea.nixg.ru pull-mirror `estorozhenko/gotosocial` (интервал 8ч), первая синхронизация ✅ (коммит d385d8b) ### Caddy vps02 (шаг 2)
- 2026-09-06: Caddyfile: `social.dedinit.ru { reverse_proxy 10.8.0.2:8082 }` + reload
(бэкап Caddyfile.bak-1788723018), сертификат LE выпущен сразу, сайт 200
### Split-domain apex Jino (шаг 3)
- 2026-09-06: .htaccess/mod_rewrite на Jino НЕ работают (проверено) → статический ответ:
- `/.well-known/webfinger?resource=...` → Apache 301 → `/webfinger/` → 200 JSON (index.html)
- `/.well-known/nodeinfo` → 301 → `/nodeinfo/` → 200 JSON
- `/.well-known/host-meta` → 200 XRD (text/xml)
- Файлы в `/dedinit.ru/.well-known/` (Jino) + `/opt/dedinit.ru/static/.well-known/` (в git, Hugo копирует)
### Крон бэкапа (шаг 4)
- 2026-09-06: backup.sh переписан на SQLite Backup API через python3 (sqlite3 CLI нет ни на хосте,
ни в контейнере); медиа из data/ (это и есть /gotosocial/storage), SQLite отдельно
- 2026-09-06: cron `gotosocial-backup-daily` (id 67308da56b6d), daily 02:00, no_agent, deliver local,
тихий (пустой stdout при успехе), проверен немедленным запуском (3 бэкапа 19:41-19:42)
- Локально 7 дней, ЯД 30 дней
### Git
- 2026-09-06: gotosocial commit d9951b6 запушен на gitverse (56f228a..d9951b6)
- 2026-09-06: dedinit.ru commit b049cb2 запушен на gitverse (3d2f07b..b049cb2)
## В работе / Следующие шаги ## В работе / Следующие шаги
- [ ] **Развернуть сервис на bigbox**: `cd /opt/gotosocial && docker compose up -d` + создание админа estorozhenko (нужен пароль от пользователя) - [ ] Проверить SMTP-письмо (регистрация/восстановление пароля) — через админку
- [ ] **Caddy на vps02**: блок `social.dedinit.ru { reverse_proxy 10.8.0.2:8080 }` + reload (нужен доступ vps02) - [ ] Мониторинг: пробросить :9464 (метрики уже слушают), job в prometheus.yml, дашборд Grafana
- [ ] **Split-domain apex**: .well-known редиректы (webfinger/nodeinfo/host-meta) на dedinit.ru (Jino) — подготовить точные правила (инструкция по метрикам GtS получена от пользователя 2026-09-06)
- [ ] Проверить HTTPS (сертификат LE), webfinger, SMTP-письмо, /metrics - [ ] Логи в json-формате при желании (log-format: json) — по умолчанию logfmt
- [ ] Настроить cron бэкапа (backup.sh готов; расписание ещё нет)
## Отложено (post-MVP, по решению пользователя) ## Отложено (post-MVP, по решению пользователя)
- Мониторинг бэкапов (метрики в Prometheus + дашборд Grafana) - Мониторинг бэкапов (метрики в Prometheus + дашборд Grafana)
- Дашборд Grafana для GtS
- Импорт из Telegram - Импорт из Telegram
## Как запустить / проверить ## Как запустить / проверить
@@ -36,20 +56,20 @@
```bash ```bash
cd /opt/gotosocial cd /opt/gotosocial
docker compose up -d docker compose up -d
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/ # 200 curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8082/ # 200
curl -s http://127.0.0.1:8080/metrics | grep -E 'go_goroutines|gin_|bun_' curl -s http://127.0.0.1:9464/metrics | head # метрики (в контейнере)
curl -s 'https://social.dedinit.ru/.well-known/webfinger?resource=acct:estorozhenko@dedinit.ru' curl -s 'https://social.dedinit.ru/.well-known/webfinger?resource=acct:estorozhenko@dedinit.ru'
curl -s 'https://dedinit.ru/.well-known/webfinger?resource=acct:estorozhenko@dedinit.ru' # apex JSON
bash backup.sh && ls -lh backups/ bash backup.sh && ls -lh backups/
``` ```
## Ключевые артефакты ## Ключевые артефакты
- /opt/gotosocial/docker-compose.yml, config.yaml, .env, backup.sh, README.md - /opt/gotosocial/docker-compose.yml, .env, backup.sh, README.md (config.yaml — reference, НЕ читается образом)
- /opt/gotosocial/openspec/changes/deploy-gotosocial/ (change)
- gitverse.ru/kpa39l/gotosocial (истина), gitea.nixg.ru/estorozhenko/gotosocial (зеркало) - gitverse.ru/kpa39l/gotosocial (истина), gitea.nixg.ru/estorozhenko/gotosocial (зеркало)
- /opt/dedinit.ru/static/.well-known/ (apex, в git b049cb2)
## Открытые вопросы ## Открытые вопросы
- Пароль админа estorozhenko для первого запуска - Пароль админа: создан с паролем из сессии (если менялся — обновить в заметках)
- Готовность vps02 к правке Caddyfile (нужен SSH) - ZFS-бэкапы/другие ротации не требуются (хватает local 7д + ЯД 30д)
- Точные .well-known редиректы на apex (Jino) — подготовить и применить
+33 -15
View File
@@ -2,35 +2,52 @@
# ============================================================= # =============================================================
# GoToSocial backup: SQLite consistent + медиа → backups/ # GoToSocial backup: SQLite consistent + медиа → backups/
# + копия на Яндекс.Диск (ротация 7 дней локально / 30 на ЯД) # + копия на Яндекс.Диск (ротация 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 set -euo pipefail
BASE_DIR="/opt/gotosocial" BASE_DIR="/opt/gotosocial"
DATA_DIR="${BASE_DIR}/data" DATA_DIR="${BASE_DIR}/data"
BACKUP_DIR="${BASE_DIR}/backups" BACKUP_DIR="${BASE_DIR}/backups"
YANDEX_DIR="/mnt/yandex-disk/backup/gotosocial-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)" TS="$(date +%Y%m%d_%H%M%S)"
# --- SQLite consistent: VACUUM INTO (не горячая копия файла) ---
SQLITE_TMP="${BACKUP_DIR}/sqlite-consistent-${TS}.db"
mkdir -p "${BACKUP_DIR}" mkdir -p "${BACKUP_DIR}"
sqlite3 "${DATA_DIR}/sqlite.db" "VACUUM INTO '${SQLITE_TMP}';" rm -rf "${STAGE}" && mkdir -p "${STAGE}"
# --- Сбор архива: consistent db + медиа --- # --- Компактный снапшот БД через 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" ARCHIVE="${BACKUP_DIR}/gotosocial_${TS}.tar.gz"
tar -C "${DATA_DIR}" -czf "${ARCHIVE}" \ tar -C "${STAGE}" -czf "${ARCHIVE}" .
--transform="s|sqlite-consistent-${TS}.db|sqlite.db|" \
"${SQLITE_TMP#${DATA_DIR}/}" storage 2>/dev/null \
|| tar -C "${BACKUP_DIR}" -czf "${ARCHIVE}" "sqlite-consistent-${TS}.db" -C "${DATA_DIR}" storage
rm -f "${SQLITE_TMP}"
# --- Архив секретов (.env) отдельно --- # --- Архив секретов (.env) отдельно ---
ENV_ARCHIVE="${BACKUP_DIR}/gotosocial_env_${TS}.tar.gz" ENV_ARCHIVE="${BACKUP_DIR}/gotosocial_env_${TS}.tar.gz"
tar -C "${BASE_DIR}" -czf "${ENV_ARCHIVE}" .env tar -C "${BASE_DIR}" -czf "${ENV_ARCHIVE}" .env
# --- Копия на Яндекс.Диск --- # --- Копия на Яндекс.Диск ---
if ! mountpoint -q "${YANDEX_DIR%/backup/*}"; then if ! mountpoint -q "${YANDEX_MOUNT}"; then
echo "ERROR: Яндекс.Диск не примонтирован (${YANDEX_DIR%/backup/*})" >&2 echo "ERROR: Яндекс.Диск не примонтирован (${YANDEX_MOUNT})" >&2
exit 1 exit 1
fi fi
mkdir -p "${YANDEX_DIR}" mkdir -p "${YANDEX_DIR}"
@@ -40,6 +57,7 @@ cp -p "${ARCHIVE}" "${ENV_ARCHIVE}" "${YANDEX_DIR}/"
find "${BACKUP_DIR}" -maxdepth 1 -type f -name 'gotosocial_*' -mtime +7 -delete find "${BACKUP_DIR}" -maxdepth 1 -type f -name 'gotosocial_*' -mtime +7 -delete
find "${YANDEX_DIR}" -maxdepth 1 -type f -name 'gotosocial_*' -mtime +30 -delete find "${YANDEX_DIR}" -maxdepth 1 -type f -name 'gotosocial_*' -mtime +30 -delete
echo "OK: ${ARCHIVE}" rm -rf "${STAGE}"
echo "OK: ${ENV_ARCHIVE}"
ls -lh "${ARCHIVE}" "${ENV_ARCHIVE}" # Успех — тихо (для no_agent cron)
exit 0