Files
admin/.wiki/concepts/galleries-storage-class-local-not-s3.md
vitya f04426617c feat(galleries): migrate pilorama98 gallery originals Local-disk → S3
snolla galleries 404 (imgproxy "Source unreachable"): legacy storageClient
"galleries" = MoreThenCms Local storage class (App_Data\galleries\<siteId>),
never in S3 — products were migrated, galleries weren't. Path A (user pick):
new bucket `galleries`, 301 pilorama98 originals (77 MiB) rclone'd from RUVDS
IIS → s3://galleries/37e6…/<guid>.jpg verbatim. snolla code unchanged
(storageClient=bucket is the working convention). imgproxy smoke from
books-vds: real obj 200 image/webp, fake guid 404. Other sites unmigrated
(scope). Inbox sent to victor/snolla.

- close [migrate-gallery-originals-to-s3] (scope pilorama98)
- NEW .wiki concept galleries-storage-class-local-not-s3
- fix stale minio-imgproxy-on-vds (pipeline on books-vds since 2026-06-08)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 14:50:16 +03:00

59 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: MoreThenCms galleries — Local storage class, never in S3 (snolla imgproxy 404 root cause)
status: resolved for pilorama98 (2026-06-12); other sites unmigrated
tags: [cms, snolla, morethencms, minio, imgproxy, s3, galleries, migration]
related: [[minio-imgproxy-on-vds]], [[../entities/books-vds]], [[../entities/ruvds-iis-host]]
---
# Galleries storage class = Local (disk), not S3
## Root cause
В MoreThenCms `<fileStorageClients>` (Web.config) каждый `storageClient` — это **алиас конфига**, не имя бакета. Алиас `galleries` маппится на тип **`MoreThenCms.FileStorage.Local.GalleriesStorage`** → файлы на локальном диске IIS:
```
C:\sites\snolla\App_Data\galleries\<siteId:N>\<storageFilename-guid>.<ext>
```
То же у `assets`, `images`, `scripts`, `stylesheets`, `watermarks` — все **Local**. Продукты (e-commerce) — другой механизм, **реально в S3** (bucket `pilorama98`, prefix `products/`, шард по hex, без siteId).
Переписка **snolla** (Node) наивно строит источник как `s3://${image.storageClient}/${siteId}/${storageFilename}` (`packages/snolla/middleware/galleries.js:47`, `lib/viewModels/index.js:289`) — т.е. ждёт галереи в S3 в бакете с именем `galleries`. Но их там никогда не было → imgproxy «Source image is unreachable» (404). Это НЕ баг билдера URL и НЕ поломка ресайза — просто **данные не мигрированы** из Local-диска в S3.
Симптом-близнец на legacy-prod (`pilorama98.ru/galleries/<id>/images/<size>/<seq>.jpg`): `original/*` = 200 (читает диск), любой ресайз = 404 — отдельная мёртвая ветка legacy-ресайзера (System.Drawing/image-cache). Целевая архитектура = imgproxy, legacy-ресайз не чинится.
## Fix recipe (путь A — выбран)
storageClient как **имя бакета** = рабочая конвенция snolla. Заливаем Local-диск в одноимённый bucket, ключи verbatim — код snolla не меняется:
```powershell
# на RUVDS IIS (rclone v1.74.2 уже стоит). env-var remote, без записи cred в rclone.conf
$env:RCLONE_CONFIG_MIN_TYPE='s3'; $env:RCLONE_CONFIG_MIN_PROVIDER='Minio'
$env:RCLONE_CONFIG_MIN_ACCESS_KEY_ID='<minio-access>'; $env:RCLONE_CONFIG_MIN_SECRET_ACCESS_KEY='<minio-secret>'
$env:RCLONE_CONFIG_MIN_ENDPOINT='https://minio.kzntsv.site' # books-vds S3 API за traefik
& rclone mkdir min:galleries
& rclone copy "C:\sites\snolla\App_Data\galleries\<siteId>" min:galleries/<siteId> --transfers 8
& rclone size min:galleries/<siteId> # сверить count+size с источником
```
- `<siteId>` папки на диске уже lowercase 32-hex == `ownerId` snolla (`String(site.id).replace(-).toLowerCase()`) → ключи совпадают 1:1, трансформаций не надо.
- Креды MinIO: `pass books-vds/full-env` (контейнер `minio`, env `MINIO_ACCESS_KEY`/`MINIO_SECRET_KEY`). imgproxy key/salt — env контейнера `imgproxy`.
## Smoke (важно: мимо LAN-DNS воркстейшна)
`imgproxy.kzntsv.site` с воркстейшна резолвится в `127.0.0.1` (LAN-перехват CMS-доменов) — смоук гнать **с самого books-vds** или `--resolve …:89.253.255.133`:
```bash
curl -sk --resolve imgproxy.kzntsv.site:443:127.0.0.1 'https://imgproxy.kzntsv.site/<sig>/fill/W/H/ce/0/<b64url(s3://galleries/<siteId>/<guid>.jpg)>.webp'
# подпись: base64url( HMAC_SHA256(KEY_bin, SALT_bin + path) ), KEY/SALT = hex из env imgproxy
```
Реальный объект → 200 image/webp; несуществующий guid → 404 (негативный контроль).
## Status / scope
- **pilorama98** (siteId `37e67fc44b9e4c06a522a26a73bac9b0`): мигрирован 2026-06-12 — 301 файл / 77 MiB, imgproxy 200 verified.
- **Остальные ~40 siteId-папок** в `App_Data\galleries`НЕ мигрированы (часть пустые). Bucket `galleries` shared; заполнен только префикс pilorama98. Другие сайты в snolla → 404 пока не зальёшь (регрессии нет).
- Если поднимаются другие Local-классы (`assets`/`images`/…) в snolla через imgproxy — их ждёт та же дыра, тот же рецепт.
См. задачу `.tasks/STATUS.md``[migrate-gallery-originals-to-s3]`.