feat(storage): S3-совместимое хранилище файлов (SeaweedFS/MinIO) и миграция uploads
- storage.js: абстракция хранилища с драйверами local и s3 (AWS SDK v3), ключи объектов совпадают с текущими путями /uploads/<файл>, поэтому схема БД и URL не меняются - docker-compose.yml: сервис s3 (SeaweedFS, том s3-data, API только на loopback), переменные S3_*/STORAGE_*, restart unless-stopped для app и db - docker-compose.minio.yml: оверрайд S3-сервиса на MinIO (образ из своего зеркала) - server.js/worker.js: чтение и запись файлов только через storage (отдача /uploads/*, миниатюры, share-файлы, zip-отчёты, enhance/apply/rollback, photo-worker), автосоздание бакета, глобальная персистенция загрузок multer - бэкап/восстановление и scripts/backup.sh, restore.sh — через scripts/storage-sync.js - scripts/migrate-to-s3.js: идемпотентная миграция uploads/ в бакет (--dry-run, --verify-only, --delete-local) - админка: блок «Хранилище» в системной информации - .env.example, README.md, AGENTS.md: описание драйверов, переменных и перехода на S3
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
const path = require('path');
|
||||
const { createStorage } = require('../storage');
|
||||
|
||||
function usage() {
|
||||
console.log(`Экспорт/импорт файлов хранилища (для scripts/backup.sh и scripts/restore.sh).
|
||||
|
||||
Использование:
|
||||
node scripts/storage-sync.js export <каталог> выгрузить все объекты в каталог
|
||||
node scripts/storage-sync.js import <каталог> загрузить все файлы из каталога в хранилище
|
||||
|
||||
Работает с текущим драйвером из переменных окружения (local — ./uploads, s3 — бакет MinIO/S3).`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const [, , mode, dirArg] = process.argv;
|
||||
if (!mode || !dirArg || mode === '--help' || mode === '-h') {
|
||||
usage();
|
||||
return process.exit(mode ? 0 : 2);
|
||||
}
|
||||
const dir = path.resolve(dirArg);
|
||||
const storage = createStorage({ dir: path.join(__dirname, '..', 'uploads') });
|
||||
if (mode === 'export') {
|
||||
const count = await storage.downloadAll(dir);
|
||||
console.log(`Экспортировано объектов: ${count} -> ${dir}`);
|
||||
return;
|
||||
}
|
||||
if (mode === 'import') {
|
||||
const count = await storage.uploadTree(dir);
|
||||
console.log(`Импортировано файлов: ${count} <- ${dir}`);
|
||||
return;
|
||||
}
|
||||
usage();
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error('storage-sync failed:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user