Перейти к основному содержимому

Снимки версий проектов в S3

Полный JSON истории хранится в отдельном приватном бакете S3. PostgreSQL хранит метаданные, SHA-256 и ключ объекта. Новая версия при выбранном S3 сначала записывается напрямую в бакет; после подтверждения загрузки PostgreSQL фиксирует метаданные без JSONB-снимка. Если S3 недоступен, снимок сохраняется в project_versions.snapshot со статусом ожидания, чтобы не потерять версию; фоновый обработчик повторит загрузку. Старые снимки при миграции также остаются в JSONB до проверки загруженного объекта.

Настройка​

Создайте отдельную конфигурацию storage_configs типа s3 без publicUrlBase и с правами на запись, чтение, перечисление и удаление объектов бакета. В админке откройте История версий → Добавить S3-хранилище, введите приватный бакет и ключи, затем сохраните выбор S3. Форма сначала создаёт конфигурацию и проверяет соединение; сохранение выбора дополнительно проверяет запись, чтение и удаление тестового объекта. Выбор хранится в app_settings и действует для новых версий; VERSION_SNAPSHOT_STORAGE_ID служит начальным значением до первого выбора в админке. Для возврата к записи полных снимков в PostgreSQL выберите PostgreSQL. Версии, уже находящиеся в S3, останутся там и будут читаться по сохранённому ключу.

Админские API для автоматизации: POST /api/storage-configs создаёт приватный S3-конфиг (name, backend: "s3", readOnly: false, config: { endpointUrl, region, bucket, forcePathStyle }, s3AccessKeyId, s3SecretAccessKey); POST /api/storage-configs/:id/test проверяет доступ; GET /admin/api/version-storage возвращает доступные конфигурации и счётчики; PUT /admin/api/version-storage с { "mode": "s3", "storageId": "..." } включает запись новых версий в выбранный бакет; POST /admin/api/version-storage/migrate запускает перенос старых версий. Все операции записи требуют авторизации администратора. Секреты передаются только в запросе создания и в ответах не возвращаются.

Локально для существующего Silo доступна команда node --import tsx tools/configure-local-version-silo.ts: она создаёт бакет tbb-project-versions-local и конфигурацию silo-project-versions-local, используя уже сохранённое подключение silo-bot-builds-local. В продакшене выберите ID отдельной конфигурации для назначенного бакета. Хранилище медиафайлов переключать не требуется.

После выбора S3 новые версии сразу записываются в бакет. Нажмите Мигрировать версии в S3, чтобы перенести ранее созданные снимки из PostgreSQL. Панель показывает количество снимков в PostgreSQL, в очереди и в S3. Запрос на перенос сохраняется в базе: фоновый обработчик продолжит работу после перезапуска. Повторный запуск безопасен. Для ручной диагностики доступна команда node --import tsx tools/migrate-project-versions-s3.ts. Существующая схема резервирования PostgreSQL продолжает работать; отдельный дамп для запуска переноса не требуется.

Проверка и восстановление​

Список версий читается только из PostgreSQL. При сравнении или откате API загружает объект и проверяет размер и SHA-256. Если объект отсутствует или повреждён, откат останавливается без изменения проекта.

Резервная копия одной базы после переноса не содержит полный архив версий. При восстановлении используйте существующую точку восстановления PostgreSQL вместе с соответствующей копией бакета версий. Для проверенной локальной копии обоих компонентов выполните node --import tsx tools/backup-project-versions-s3.ts <каталог>; сам каталог затем скопируйте за пределы сервера. Отдельный дамп нужен только если текущая система резервирования не позволяет восстановить нужную точку.

При восстановлении остановите API, восстановите базу вместе с конфигурациями хранилищ и обеспечьте прежний STORAGE_ENCRYPTION_KEY для расшифровки S3-ключей. Затем выполните node --import tsx tools/restore-project-versions-s3.ts <каталог> и node --import tsx tools/verify-project-versions-s3.ts --all. Запускайте API только после успешной проверки каждого объекта по размеру и SHA-256. До завершения проверки не удаляйте исходные копии.

Очистка JSONB освобождает логическое место в таблице. Для возврата физического места операционной системе PostgreSQL может потребоваться отдельное обслуживание таблицы, например VACUUM FULL project_versions, которое блокирует её на время операции. Планируйте его в окно обслуживания после проверенного бэкапа; обычную работу приложения ради него не останавливайте.

Удалённые версии ставятся в очередь project_version_object_deletions триггером базы, в том числе при каскадном удалении проекта. Фоновый процесс удаляет объект после суточной паузы, оставляющей время снять согласованную копию бакета после дампа БД. Ежедневная сверка убирает объекты-сироты старше суток. Для наблюдения выполните node --import tsx tools/project-versions-s3-status.ts: команда показывает число ожидающих переноса старых версий, возраст старейшей и размер очереди удаления. При сбое S3 ожидающие переноса снимки остаются в базе и будут повторно обработаны после восстановления соединения.