Files
image-gateway/docs/overview.md
S.Gromov 0751c4b469 feat: добавить Image Gateway с кешем Souin
- добавлена сборка Caddy с Souin, Otter и NutsDB

- добавлена конфигурация dev, prod и test Docker Compose

- настроено кеширование через Otter L1 и NutsDB L2

- добавлены e2e-тесты Bun для кеша, restart и purge

- добавлена документация по запуску, API кеша и тестам
2026-05-04 12:18:37 +03:00

93 lines
4.1 KiB
Markdown
Raw Permalink 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.

# Обзор проекта
## Что это
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 или напрямую