85 lines
3.0 KiB
Markdown
85 lines
3.0 KiB
Markdown
|
|
# Архитектура
|
|||
|
|
|
|||
|
|
## Назначение
|
|||
|
|
|
|||
|
|
`image-platform` - отдельный control plane для своего Cloudinary-like image pipeline.
|
|||
|
|
|
|||
|
|
Проект отвечает за metadata, S3 artifacts, variants, allowlist, presets и генерацию изображений через внешний `imgproxy`.
|
|||
|
|
|
|||
|
|
## Компоненты
|
|||
|
|
|
|||
|
|
| Компонент | Статус | Роль |
|
|||
|
|
|---|---|---|
|
|||
|
|
| PostgreSQL | сейчас | Источник правды для assets, variants, hosts, statuses |
|
|||
|
|
| S3/MinIO | сейчас | Хранилище originals и generated variants |
|
|||
|
|
| API | позже | JSON API, admin operations, validation, orchestration |
|
|||
|
|
| Worker | позже | Генерация variants, upload в S3, update PostgreSQL |
|
|||
|
|
| Admin UI | позже | Управление hosts/assets/variants/presets |
|
|||
|
|
| Gateway | позже | Caddy/Souin hot cache и delivery layer |
|
|||
|
|
| imgproxy | external | CPU-heavy image processing |
|
|||
|
|
|
|||
|
|
## Целевая delivery схема
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
client
|
|||
|
|
-> CDN optional
|
|||
|
|
-> gateway Caddy/Souin
|
|||
|
|
-> S3 ready variant
|
|||
|
|
-> generator fallback
|
|||
|
|
-> external imgproxy
|
|||
|
|
-> source image
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Разделение ответственности
|
|||
|
|
|
|||
|
|
PostgreSQL отвечает на вопросы:
|
|||
|
|
|
|||
|
|
- какие assets зарегистрированы;
|
|||
|
|
- какие variants созданы;
|
|||
|
|
- где variants лежат в S3;
|
|||
|
|
- какие variants `pending`, `processing`, `ready`, `failed`;
|
|||
|
|
- сколько bytes занимает asset/project/user;
|
|||
|
|
- какие source hosts разрешены.
|
|||
|
|
|
|||
|
|
S3 хранит байты:
|
|||
|
|
|
|||
|
|
- original images, если решим сохранять originals;
|
|||
|
|
- generated variants;
|
|||
|
|
- metadata объектов на уровне storage, но не бизнес-логику.
|
|||
|
|
|
|||
|
|
Gateway отдаёт картинки:
|
|||
|
|
|
|||
|
|
- hot cache HIT - сразу из Souin;
|
|||
|
|
- cache MISS - из S3;
|
|||
|
|
- S3 MISS - через generator fallback.
|
|||
|
|
|
|||
|
|
Backend не должен проксировать картинки на каждый обычный запрос. Он отдаёт JSON, статусы и URLs.
|
|||
|
|
|
|||
|
|
## URL модель
|
|||
|
|
|
|||
|
|
Публичные URL должны быть стабильными и не раскрывать source URL:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
/images/{assetId}/{variantHash}.{format}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Примеры:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
/images/asset_123/w640_q80_cfill.avif
|
|||
|
|
/images/asset_123/w640_q80_cfill.webp
|
|||
|
|
/images/asset_123/w640_q80_cfill.jpg
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Формат лучше делать явным в URL и отдавать через `<picture>`/`srcset`, а не выбирать по `Accept` header. Так CDN/S3/Gateway cache остаётся предсказуемым.
|
|||
|
|
|
|||
|
|
## External imgproxy
|
|||
|
|
|
|||
|
|
`imgproxy` не входит в этот проект и не деплоится вместе с ним. Он подключается через env:
|
|||
|
|
|
|||
|
|
```env
|
|||
|
|
IMGPROXY_UPSTREAM=http://external-imgproxy.internal:8080
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Это позволяет держать image processing на отдельной мощной машине и не рисковать основным сервером.
|