An experimental image resizing http service that wraps ImageMagick to provide safe & accurate dynamic image resizing. The best way to utilize the Rusty Resizer is through a Docker container and behind a CDN.
The Rusty Resizer is wrapped in a minimal Docker container (image size is less than < 100MBs) that can be easily mounted as a standalone service:
docker run -p 8080:8080 --env ALLOWED_HOSTS=raw.githubusercontent.com ghcr.io/walterbm/rusty-resizer:latest
- Install Rust
- Install ImageMagick
- Install Dependencies
cargo install --path .
- Start the Server
cargo run
Start the Rusty Resizer server (either through Docker or with Cargo). By default the server will start on port 8080
.
The server only exposes two endpoints:
/resize
to resize images/ping
as a health check
Once the server is running images can be dynamically resized through the /resize
endpoint. For example:
curl localhost:8080/resize?source=image.jpeg&height=100&width=100&quality=85&format=webp
/resize
accepts four query parameters:
source
: required to specify the full url of the target imageheight
&width
: the resized image's dimensions (ifheight
orwidth
are alone the other dimension is computed to preserve the aspect ratio)quality
: optionally set the compression quality for image formats that accept compression (e.g. jpeg)format
: convert the source to another format during the resize operation (e.g. png -> jpeg) and if set toformat=auto
attempt to automatically convert the source image toWebP
based on client'sAccept
header
The Rusty Resizer accepts all its configuration options through ENV variables:
ENV var | description | default |
---|---|---|
ALLOWED_HOSTS |
required list of image hosts that will be accepted for resizing | |
DEFAULT_QUALITY |
default compression quality for image formats that accept compression (e.g. jpeg) | 85 |
CACHE_EXPIRATION_HOURS |
used to populate Cache-Control & Expires headers in the final resized response |
2880 hours |
CACHE_JITTER_SECONDS |
help give Cache-Control & Expires headers some variance to avoid a thundering herd |
0 |
STATSD_HOST |
StatsD host to accept metric data (metrics are only emitted when this is present) | |
WORKERS |
number of HTTP workers | 4 |
PORT |
TCP port to bind the server | 8080 |
ENV |
environment the server is running in | local |
For security, and to mitigate some of the worst vulnerabilities in ImageMagick, the Rusty Resizer requires an $ALLOWED_HOSTS
ENV variable.
Only images originating from hosts explicitly listed in $ALLOWED_HOSTS
will be accepted by the Rusty Resizer. For example to make sure the following request works as expected ALLOWED_HOSTS
should be set to raw.githubusercontent.com
:
curl localhost:8080/resize?source=https://raw.githubusercontent.com/image.jpeg&height=100&width=100
For best results deploy the Rusty Resizer behind a CDN to help amortize the cost of resizing an image. If the CDN respects standard cache headers the cache time for the the resized images can be controlled through the CACHE_EXPIRATION_HOURS
ENV option.
If using automatic content negotiation with the format=auto
parameter make sure the CDN in front of the the Rusty Resizer respects the outgoing Vary
header and/or can be configured to incorporate the incoming Accept
header into the cache key. To optimize cache performance add some pre-processing to the CDN to normalize the Accept
header.
Run the test suite with:
cargo test
Distributed under the MIT License. See LICENSE
for more information.