# SILO → ACORE media + Nextcloud SILO ([pgsty/silo](https://silo.pigsty.io/)) — S3-совместимое хранилище (форк MinIO). Портал **не** ходит в S3 за документами: документы остаются через Nextcloud WebDAV. SILO — бэкенд файлов Nextcloud и Django `MEDIA` (фото и т.п.). ``` ACORE ImageField ──▶ bucket acore-media (SILO) ACORE Documents ──▶ Nextcloud WebDAV ──▶ bucket nextcloud (SILO) ``` ## 0. SILO: бакеты и ключи На машине с доступом к API SILO (`:9000`): ```bash export SILO_ENDPOINT=https://s3.example.local:9000 export SILO_ROOT_USER=... export SILO_ROOT_PASSWORD=... chmod +x scripts/silo_bootstrap.sh ./scripts/silo_bootstrap.sh ``` Скрипт создаёт: | Bucket | Пользователь | Назначение | |--------|--------------|------------| | `acore-media` | `acore-media-rw` | Django media | | `nextcloud` | `nextcloud-rw` | Primary object store NC | Включает versioning и smoke put/get. Root-ключ после bootstrap для приложений не использовать. Проверка с хостов ACORE и Nextcloud: ```bash mcli alias set check "$SILO_ENDPOINT" acore-media-rw "$S3_SECRET_KEY" mcli ls check/acore-media ``` TLS: лучше reverse-proxy (Traefik/nginx) на API; клиентам — `https://…`. ## 1. Nextcloud: primary object store 1. Остановить NC, бэкап data-dir (`config/`, `data/`). 2. В `config/config.php` добавить **до** первого запуска с новым store (или через occ, если версия поддерживает): ```php 'objectstore' => [ 'class' => '\\OC\\Files\\ObjectStore\\S3', 'arguments' => [ 'bucket' => 'nextcloud', 'autocreate' => false, 'key' => 'nextcloud-rw', 'secret' => 'PASTE_SECRET', 'hostname' => 's3.example.local', 'port' => 9000, 'use_ssl' => true, 'use_path_style' => true, 'region' => 'us-east-1', // при необходимости: 'legacy_auth' => true, ], ], ``` `hostname` — хост **без** схемы; порт отдельно. Path-style обязателен для SILO/MinIO. 3. Если на локальном диске уже есть файлы пользователей — миграция отдельным окном (occ files:scan / инструменты вендора, либо чистый стенд). Не монтируйте тот же бакет как External Storage *и* primary одновременно для одних и тех же данных. 4. Запуск NC → upload в UI → с портала browse/upload документов и документов аптеки (WebDAV без изменений в ACORE). 5. Логи: `nextcloud.log`, ошибки `objectstore` / S3. **External Storage** (админка → Внешнее хранилище) — только если нужна *дополнительная* шара рядом с локальным диском. Для «все документы портала в SILO» нужен именно **primary object store**, как выше. ## 2. ACORE media В `.env` (секреты из вывода bootstrap): ```env S3_ENDPOINT=https://s3.example.local:9000 S3_ACCESS_KEY=acore-media-rw S3_SECRET_KEY=... S3_MEDIA_BUCKET=acore-media S3_REGION=us-east-1 # S3_QUERYSTRING_EXPIRE=3600 ``` Если `S3_ENDPOINT` + ключи заданы — `STORAGES['default']` = S3; иначе локальный `MEDIA_ROOT` (dev). Одноразовая заливка существующего диска: ```bash python manage.py sync_media_to_s3 # или dry-run: python manage.py sync_media_to_s3 --dry-run ``` После стабилизации nginx **не** должен раздавать `/media/` с диска приложения: URL файлов — подписанные ссылки на SILO. Static по-прежнему с диска/`collectstatic`. ## Эксплуатация - Бэкап бакетов SILO отдельно от PostgreSQL (versioning ≠ бэкап). - Разные ключи на media и Nextcloud; не коммитить секреты. - После cutover локальный `media/` можно оставить read-only архивом.