Files
image-gateway/docs/usage-guide.md

273 lines
8.3 KiB
Markdown
Raw Normal View History

# Гайд использования
Руководство по кейсам — копируй, вставляй, проверяй. Без обдумывания.
## 1. Запуск
```bash
cp .env.example .env
docker compose -f docker-compose.dev.yml up -d --build
```
Проверка:
```bash
curl -s -o /dev/null -w "%{http_code}" \
"http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/plain/https://picsum.photos/200/200"
# → 200
```
## 2. Обработка изображений
### Resize — вписать в ширину 800px
```bash
curl -s -o /tmp/fit800.jpg \
"http://localhost:8888/unsafe/resize:fit:800:0:0/q:80/plain/https://picsum.photos/1200/800"
# → файл /tmp/fit800.jpg, ширина = 800px
```
### Resize — вписать в квадрат 200x200
```bash
curl -s -o /tmp/fit200.jpg \
"http://localhost:8888/unsafe/resize:fit:200:200:0/q:80/plain/https://picsum.photos/1200/800"
# → файл 200x?, пропорции сохранены
```
### Resize — заполнить 400x300 (с обрезкой)
```bash
curl -s -o /tmp/fill400.jpg \
"http://localhost:8888/unsafe/resize:fill:400:300:0/g:ce/q:80/plain/https://picsum.photos/1200/800"
# → файл точно 400x300, лишнее обрезано по центру
```
### Crop — обрезка 200x200
```bash
curl -s -o /tmp/crop200.jpg \
"http://localhost:8888/unsafe/crop:200:200/plain/https://picsum.photos/1200/800"
# → файл 200x200
```
### WebP — конвертация формата
```bash
curl -s -D - -o /tmp/webp.webp \
"http://localhost:8888/unsafe/format:webp/q:80/plain/https://picsum.photos/800/600" \
2>&1 | grep Content-Type
# → Content-Type: image/webp
```
### AVIF
```bash
curl -s -D - -o /tmp/avif.avif \
"http://localhost:8888/unsafe/format:avif/q:80/plain/https://picsum.photos/800/600" \
2>&1 | grep Content-Type
# → Content-Type: image/avif
```
### Качество — сравнить q:10 vs q:100
```bash
curl -s -o /tmp/q10.jpg \
"http://localhost:8888/unsafe/resize:fit:400:0:0/q:10/plain/https://picsum.photos/800/600"
curl -s -o /tmp/q100.jpg \
"http://localhost:8888/unsafe/resize:fit:400:0:0/q:100/plain/https://picsum.photos/800/600"
ls -la /tmp/q10.jpg /tmp/q100.jpg
# → q10 ~4KB, q100 ~50KB — разница ~12x
```
### Комбинированные — resize + WebP + качество
```bash
curl -s -o /tmp/combined.webp \
"http://localhost:8888/unsafe/resize:fit:800:0:0/g:ce/q:75/format:webp/plain/https://picsum.photos/1200/800"
# → 800px по ширине, WebP, качество 75
```
### base64url — закодированный source URL
```bash
B64=$(echo -n "https://picsum.photos/800/600" | base64 -w0 | tr '+/' '-_' | tr -d '=')
curl -s -o /tmp/b64.jpg "http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/$B64"
# → работает как plain/, но без /plain/ префикса
```
## 3. Кеширование
### MISS → HIT — базовая проверка
```bash
URL="http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/plain/https://picsum.photos/400/300"
# Первый запрос — MISS (обработка через imgproxy)
curl -s -o /dev/null -D - -w "\ntime: %{time_total}s\n" "$URL" | grep -E "Cache-Status|time"
# → Cache-Status: Souin; fwd=uri-miss; stored
# → time: 0.5s
# Второй запрос — HIT (из кеша)
curl -s -o /dev/null -D - -w "\ntime: %{time_total}s\n" "$URL" | grep -E "Cache-Status|time"
# → Cache-Status: Souin; hit; ttl=31535999; detail=DEFAULT
# → time: 0.001s
```
### Что значит Cache-Status
```
Cache-Status: Souin; hit; ... → из кеша
Cache-Status: Souin; fwd=uri-miss; stored; key=GET-... → первый запрос, закешировано
Cache-Status: Souin; fwd=uri-miss; detail=UNCACHEABLE-... → не закешировано (ошибка upstream)
```
### Разные размеры = разные ключи
```bash
SRC="https://picsum.photos/id/42/800/600"
curl -s -o /dev/null "http://localhost:8888/unsafe/resize:fit:200:0:0/q:80/plain/$SRC"
curl -s -o /dev/null "http://localhost:8888/unsafe/resize:fit:400:0:0/q:80/plain/$SRC"
curl -s "http://localhost:2019/souin-api/souin/"
# → 2 ключа: ...resize:fit:200... и ...resize:fit:400...
```
## 4. Purge кеша
> Все purge-запросы идут через Caddy Admin API на порту **2019**.
### Purge — сбросить всё
```bash
# Закешировать
curl -s -o /dev/null "http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/plain/https://picsum.photos/400/300"
# Purge
curl -s -w "status: %{http_code}\n" -X PURGE http://localhost:2019/souin-api/souin/flush
# → status: 204
# Проверить — снова MISS
curl -s -o /dev/null -D - "http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/plain/https://picsum.photos/400/300" \
| grep Cache-Status
# → Cache-Status: Souin; fwd=uri-miss; stored
```
### Purge — конкретное изображение (все размеры)
```bash
# Закешировать 2 размера
SRC="https://picsum.photos/id/77/800/600"
curl -s -o /dev/null "http://localhost:8888/unsafe/resize:fit:200:0:0/q:80/plain/$SRC"
curl -s -o /dev/null "http://localhost:8888/unsafe/resize:fit:400:0:0/q:80/plain/$SRC"
# Purge по regex (id/77)
curl -s -w "status: %{http_code}\n" -X PURGE "http://localhost:2019/souin-api/souin/.*id/77.*"
# → status: 204
# Оба размера сброшены
```
### Purge — конкретный размер
```bash
curl -s -w "status: %{http_code}\n" -X PURGE \
"http://localhost:2019/souin-api/souin/.*resize:fit:200.*id/77.*$"
# → status: 204 — только 200px сброшен, 400px остался
```
## 5. Caddy Admin API (Souin)
Порт **2019**, только localhost.
### Список закешированных ключей
```bash
curl -s http://localhost:2019/souin-api/souin/
# → ["GET-http-localhost:8888-/unsafe/resize:fit:200:0:0/q:80/plain/https://..."]
```
### Purge — все методы
```bash
# Полный сброс
curl -X PURGE http://localhost:2019/souin-api/souin/flush
# → 204
# По regex
curl -X PURGE "http://localhost:2019/souin-api/souin/.*example.com/photo.jpg"
# → 204
# Точное совпадение (с $ в конце)
curl -X PURGE "http://localhost:2019/souin-api/souin/.*resize:fit:800.*photo\.jpg$"
# → 204
```
## 6. Signed vs Unsigned
### Unsigned — по умолчанию
Ключи не заданы → `/unsafe/` работает:
```bash
# С /unsafe/ → работает
curl -s -o /dev/null -w "%{http_code}" \
"http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/plain/https://picsum.photos/200/200"
# → 200
# Без /unsafe/ → тоже работает (ключи не заданы, подпись не проверяется)
curl -s -o /dev/null -w "%{http_code}" \
"http://localhost:8888/resize:fit:100:0:0/q:80/plain/https://picsum.photos/200/200"
# → 200
```
### Signed — включить подпись
1. Сгенерировать ключи:
```bash
openssl rand -hex 32 # → KEY
openssl rand -hex 32 # → SALT
```
2. Добавить в `.env`:
```env
IMGPROXY_KEY=<сгенерированный_ключ>
IMGPROXY_SALT=<сгенерированная_соль>
```
3. Перезапустить:
```bash
docker compose -f docker-compose.dev.yml restart imgproxy
```
4. Проверить:
```bash
# Без /unsafe/ и без подписи → ошибка
curl -s -o /dev/null -w "%{http_code}" \
"http://localhost:8888/resize:fit:100:0:0/q:80/plain/https://picsum.photos/200/200"
# → 403
# С /unsafe/ → тоже ошибка (ключи заданы, unsafe запрещён)
curl -s -o /dev/null -w "%{http_code}" \
"http://localhost:8888/unsafe/resize:fit:100:0:0/q:80/plain/https://picsum.photos/200/200"
# → 403
```
5. Подписать URL:
```bash
KEY="<сгенерированный_ключ>"
SALT="<сгенерированная_соль>"
PATH_URL="/resize:fit:100:0:0/q:80/plain/https://picsum.photos/200/200"
SIG=$(echo -n "$SALT" | xxd -r -p | openssl dgst -sha256 -hmac "$(echo -n "$KEY" | xxd -r -p)" -binary | base64 | tr '+/' '-_' | tr -d '=' | head -c 32)
curl -s -o /dev/null -w "%{http_code}" "http://localhost:8888/${SIG}${PATH_URL}"
# → 200
```
6. Вернуть unsigned — убрать ключи из `.env` и перезапустить.