feat: добавить Image Gateway с кешем Souin
- добавлена сборка Caddy с Souin, Otter и NutsDB - добавлена конфигурация dev, prod и test Docker Compose - настроено кеширование через Otter L1 и NutsDB L2 - добавлены e2e-тесты Bun для кеша, restart и purge - добавлена документация по запуску, API кеша и тестам
This commit is contained in:
92
docs/overview.md
Normal file
92
docs/overview.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Обзор проекта
|
||||
|
||||
## Что это
|
||||
|
||||
Image Gateway — self-hosted сервер для обработки и кеширования изображений. Принимает URL оригинального изображения, изменяет размер/формат/качество по запросу, кеширует результат и отдаёт быстро.
|
||||
|
||||
## Зачем
|
||||
|
||||
- **Оптимизация изображений** — автоматический resize, crop, конвертация в WebP/AVIF
|
||||
- **Кеширование** — однократная обработка, последующие запросы отдаются из кеша за ~1ms
|
||||
- **Самостоятельный хостинг** — нет зависимости от внешних SaaS-сервисов (Cloudinary, imgix и т.д.)
|
||||
- **Простая интеграция** — URL-based API, совместимое с `next/image`, `<img>` и любым HTTP-клиентом
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
Клиент → Caddy (:8888)
|
||||
├─ HIT: отдаёт из кеша (~1ms)
|
||||
└─ MISS: → imgproxy → скачивает оригинал → обработка → ответ + кеширование
|
||||
```
|
||||
|
||||
### Компоненты
|
||||
|
||||
| Компонент | Роль |
|
||||
|---|---|
|
||||
| **Caddy** | Reverse proxy, кеширование (Souin plugin), HTTPS |
|
||||
| **imgproxy** | Обработка изображений (resize, crop, конвертация форматов, качество) |
|
||||
|
||||
### Маршрутизация
|
||||
|
||||
```
|
||||
Caddy (:8888)
|
||||
├─ /* → imgproxy (через кеш Souin)
|
||||
└─ /souin-api/* → Souin API (управление кешем)
|
||||
```
|
||||
|
||||
## Возможности
|
||||
|
||||
### Обработка изображений (imgproxy)
|
||||
|
||||
- **Resize** — вписать (`fit`), заполнить (`fill`), точный размер (`force`)
|
||||
- **Crop** — обрезка с указанием ширины/высоты
|
||||
- **Конвертация форматов** — JPEG, PNG, WebP, AVIF, GIF
|
||||
- **Качество** — от 1 до 100
|
||||
- **Гравитация** — `ce` (центр), `no` (север), `ea` (восток), и т.д.
|
||||
- **Подпись URL** — HMAC-SHA256 для защиты от несанкционированного использования
|
||||
- **Whitelist доменов** — ограничение источников изображений через `IMGPROXY_ALLOWED_SOURCES`
|
||||
|
||||
### Кеширование (Souin)
|
||||
|
||||
- Кеширует обработанные изображения в памяти
|
||||
- TTL по умолчанию — 1 год (определяется `Cache-Control` от imgproxy)
|
||||
- HTTP-заголовок `Cache-Status` в каждом ответе — `hit` или `miss`
|
||||
- API для программного сброса кеша (`/souin-api/souin/`)
|
||||
|
||||
### Режимы работы
|
||||
|
||||
| Режим | Описание | Защита |
|
||||
|---|---|---|
|
||||
| **Unsigned** | URL с префиксом `/unsafe/` | Whitelist доменов (`IMGPROXY_ALLOWED_SOURCES`) |
|
||||
| **Signed** | URL с HMAC-SHA256 подписью | Подпись + whitelist |
|
||||
|
||||
Unsigned режим рекомендуется для SPA-приложений — ключи подписи не утекают в браузер.
|
||||
|
||||
## Интеграция
|
||||
|
||||
### HTML
|
||||
|
||||
```html
|
||||
<img src="http://localhost:8888/unsafe/resize:fit:800:0:0/q:80/plain/https://example.com/photo.jpg" />
|
||||
```
|
||||
|
||||
### Next.js (loader)
|
||||
|
||||
```ts
|
||||
const imageGatewayLoader = ({ src, width, quality }) => {
|
||||
const q = quality ?? 80
|
||||
return `http://localhost:8888/unsafe/resize:fit:${width}:0:0/q:${q}/plain/${src}`
|
||||
}
|
||||
```
|
||||
|
||||
### Любой HTTP-клиент
|
||||
|
||||
```
|
||||
GET http://localhost:8888/unsafe/resize:fit:800:0:0/q:80/plain/https://example.com/photo.jpg
|
||||
```
|
||||
|
||||
## Что НЕ входит в проект
|
||||
|
||||
- Админ-панель — реализуется как внешний сервис (Next.js, SPA и т.д.)
|
||||
- Хранилище оригиналов — проект только обрабатывает изображения по URL
|
||||
- CDN-слой — проект работает за CDN или напрямую
|
||||
Reference in New Issue
Block a user