- добавлен shared config presets, custom transforms и allowlist hosts - реализованы Backend endpoints для assets, presets и variants - добавлена orchestration через PostgreSQL, RabbitMQ, S3 и worker - обновлён Gateway read-through flow с L1 cache и корректным Vary: Accept - добавлена миграция resize_mode для variants lookup - обновлены dev scripts, env template, lockfile и документация
5.8 KiB
Локальная разработка
Принцип
В Docker запускаем стабильную инфраструктуру. Кодовые сервисы запускаем нодой с hot reload.
Сейчас в Docker есть только:
- PostgreSQL;
- MinIO;
- MinIO bucket init;
- imgproxy dev instance;
- RabbitMQ.
backend уже умеет регистрировать assets и выполнять internal ensure. gateway уже ходит в Backend и держит L1 memory cache. worker уже читает RabbitMQ jobs, вызывает imgproxy и пишет variants в S3.
Gateway обязателен для Cloudinary-like поведения и интеграции с next/image.
Запуск инфраструктуры
cp .env.example .env
pnpm install
pnpm infra:up
pnpm db:migrate
.env используется только локально и игнорируется git. Backend, Gateway, Worker и Drizzle scripts автоматически подхватывают его через Node --env-file-if-exists; в production эти переменные должны приходить из окружения процесса.
Проверить compose config:
pnpm infra:config
Остановить:
pnpm infra:down
Логи:
pnpm infra:logs
Порты
| Сервис | URL |
|---|---|
| PostgreSQL | localhost:5433 |
| MinIO API | http://localhost:9000 |
| MinIO Console | http://localhost:9001 |
| imgproxy | http://localhost:18080 |
| RabbitMQ | amqp://localhost:5672 |
| RabbitMQ Management | http://localhost:15672 |
| Backend API | http://localhost:3001/api |
| Swagger | http://localhost:3001/docs |
| Admin | http://localhost:5173 |
| Gateway | http://localhost:8888 |
Если localhost:8888 занят старым image-gateway, остановите старый stack или задайте GATEWAY_PORT=8890 в .env.
Backend
Запустить NestJS backend:
pnpm backend:dev
Проверки:
curl http://localhost:3001/api/health
open http://localhost:3001/docs
Зарегистрировать source image в dev mode:
curl -sS -X POST http://localhost:3001/api/assets \
-H 'content-type: application/json' \
-d '{"sourceUrl":"https://storage.yandexcloud.net/shared1318/img/1.jpg","publicId":"asset_demo"}'
Посмотреть business API:
curl -sS http://localhost:3001/api/presets
curl -sS http://localhost:3001/api/assets
curl -sS http://localhost:3001/api/assets/asset_demo
curl -sS http://localhost:3001/api/assets/asset_demo/variants
Явно поставить jobs на генерацию family variants без Gateway lazy request:
curl -sS -X POST http://localhost:3001/api/assets/asset_demo/variants \
-H 'content-type: application/json' \
-d '{"preset":"card","mode":"family"}'
Database
Drizzle schema живёт в packages/database/src/schema.ts, миграции - в packages/database/drizzle.
Сгенерировать миграцию после изменения schema:
pnpm db:generate
Применить миграции к локальному PostgreSQL:
pnpm db:migrate
Открыть Drizzle Studio из корня проекта:
pnpm db:studio
Проверить database package:
pnpm db:typecheck
pnpm db:build
Admin
Запустить React/Vite admin:
pnpm admin:dev
Открыть:
open http://localhost:5173
Gateway
Gateway запускается нодой:
pnpm gateway:dev
Проверить gateway health:
curl http://localhost:8888/health
Проверить image origin route после запуска Backend и Worker:
curl -i "http://localhost:8888/images/asset_demo/v1/card?w=640&q=80&f=auto"
curl -i "http://localhost:8888/images/asset_demo/v1/avatar?f=auto"
curl -i "http://localhost:8888/images/asset_demo/v1/custom?w=777&h=333&q=72&fit=fill&f=webp"
Первый запрос должен пройти через Backend/RabbitMQ/Worker/imgproxy/S3 и вернуться с x-image-platform-l1: MISS. Повторный запрос должен вернуться из gateway L1 с x-image-platform-l1: HIT.
Статические presets сейчас лежат в packages/image-config:
card- responsive, widths320,640,960.hero- responsive, widths1280,1920.avatar- fixed256x256.
Mock allowlist source hosts задаётся через SOURCE_ALLOWED_HOSTS. В dev по умолчанию разрешён storage.yandexcloud.net.
Worker
Worker запускается нодой, объявляет RabbitMQ topology, слушает image.generate-variant, вызывает imgproxy и пишет готовый variant в S3.
pnpm worker:dev
Проверить worker package без запуска consumer:
pnpm worker:typecheck
pnpm worker:build
Будущий dev flow
Текущая и будущая схема:
React/Vite admin localhost:5173
-> NestJS backend localhost:3001
-> PostgreSQL localhost:5433
-> MinIO localhost:9000
-> RabbitMQ localhost:5672
worker node process
-> PostgreSQL
-> MinIO
-> RabbitMQ
-> imgproxy localhost:18080
Fastify gateway localhost:8888
-> L1 memory cache
-> Backend internal ensure endpoint
imgproxy для разработки
В dev compose поднимается локальный imgproxy, опубликованный только на 127.0.0.1:18080:
IMGPROXY_UPSTREAM=http://localhost:18080
Для production imgproxy всё равно рассматривается как внешняя зависимость и может жить на отдельном мощном сервере.