Высоконагруженный CDN-сервис на Rust + Actix с Postgres и ресайзом изображений (crate image), полностью совместимый по эндпоинтам с исходным FastAPI:
POST /images/— приём base64 и сохранение оригинала (JPEG)GET /{img_guid}/{parametr_images}— отдача JPEG по размеруHxW(лимит 1600)GET /{img_guid}/— отдача оригинала (из файла, или автодокачка поlink_o)GET /{img_guid}.{format}?odnWidth=&odnHeight=&odnBg=— отдача в выбранном формате (JPEG|PNG|GIF|TIFF|WebP)- дублированные пути с префиксом
/images/...— удар в удар с Python-реализацией
API-документация (Swagger UI) доступна на /docs (вкл/выкл через .env).
cdn-rs/
├─ Cargo.toml
├─ .env.example
├─ README.md
├─ Dockerfile
├─ docker-compose.yml # опционально
├─ .dockerignore
├─ migrations/
│ └─ 001_create_images.sql
└─ src/
├─ main.rs
├─ config.rs
├─ errors.rs
├─ db.rs
├─ proxy.rs
├─ util.rs
├─ imaging.rs
├─ openapi.rs
├─ routes/
│ └─ cdn.rs
└─ models/
└─ image.rs
- Actix + фиксированные воркеры по числу CPU (не меньше 4).
- CPU-тяжёлые операции ресайза выполняются в
spawn_blocking, не блокируя реактор. sqlxc пулом соединений (по умолчанию до 40).- Быстрый I/O, минимизация копий; контент отдаётся напрямую в ответ.
- Ленивое создание директорий и idempotent запись файлов.
- Возможность скачивания оригинала по
link_oпри первом запросе.
- Linux/WSL2/macOS
- Docker / Docker Compose (для контейнерного запуска) либо Rust 1.79+
- Postgres 13+ (в
docker-compose.ymlуже есть готовый сервис)
-
Скопируйте пример окружения и поправьте значения:
cp .env.example .env
-
(Опционально) создайте локальную папку под медиа:
mkdir -p ./media
-
Поднимите сервисы:
docker compose up -d --build
-
Проверьте сервис:
- Swagger: http://localhost:8080/docs
- OpenAPI JSON: http://localhost:8080/api-docs/openapi.json
База данных поднимется автоматически, таблица создастся при применении миграции (см. ниже).
| Переменная | Описание | Значение по умолчанию |
|---|---|---|
BIND_ADDR |
Адрес/порт HTTP-сервера | 0.0.0.0:8080 |
MEDIA_BASE_DIR |
Путь хранения файлов (аналог castom_addres) |
/var/www/onlihub/data/www/onlihub-media.com/ |
NO_IMAGE_FILE |
Имя файла-заглушки внутри MEDIA_BASE_DIR |
no-image-01.jpg |
MAX_IMAGE_SIDE |
Лимит на сторону при ресайзе | 1600 |
DATABASE_URL |
Строка подключения к Postgres | — (обязательна) |
SWAGGER_ENABLED |
Включить Swagger UI (true/false) |
true |
SWAGGER_TITLE |
Заголовок для Swagger | Onlihub Media CDN |
SWAGGER_VERSION |
Версия API в Swagger | 1.0.0 |
USE_PROXIES |
Включить случайные HTTP(S) прокси при скачивании оригиналов (true/1) |
false |
create table if not exists images (
id bigserial primary key,
guid uuid not null unique,
link_o text,
status int,
status_date timestamptz
);
create index if not exists images_guid_idx on images(guid);
create index if not exists images_link_o_idx on images(link_o);