Nginx image resize configuration
Nginx's image filter plugin has the ability to dynamically resize images. Caching the resized files is not yet integrated into the module, but it is possible by using an internal proxy request.
This code will resize images based on the height and width given in the url, E.G.
/dyn_images/sample-100-20.jpg will return
sample.jpg resized proportionally to 100x20px.
location /dyn_images {
if ($request_filename ~ [a-zA-Z0-9]+-([0-9]+)-([0-9]+).jpg) {
set $img_width $1;
set $img_height $2;
rewrite ^(.*)-[0-9]+-[0-9]+.jpg$ $1.jpg break;
}
image_filter resize $img_width $img_height;
image_filter_buffer 1M;
}
The
rewrite directive is necessary because
image_filter gets the filename from
$request_filename.
Caching the resized images
Resizing is best done by a separate server because it can be cpu demanding, but here goes:
location /cached_dyn_images/ {
alias /tmp/nginx_tmp/image_resize/;
set $image_uri "image_resize/none.jpg";
if ($request_uri ~ "/virtual/images/(.*)-([0-9]+)x([0-9]+)\.([a-z0-9]+)$") {
set $image_uri image_resize/$1.$4?width=$2&height=$3;
set $image_filename $1-$2x$3.$4;
}
if (!-f $request_filename) {
proxy_pass http://127.0.0.1/$image_uri;
break;
}
proxy_store /mnt/nginx_tmp/image_resize/$image_filename;
proxy_store_access user:rw group:rw all:r;
proxy_temp_path /tmp/images;
# if you have several virtualhosts you need this
proxy_set_header Host $host;
}
location /real_dyn_images {
alias /var/www/images;
set $img_width $arg_width;
set $img_height $arg_height;
image_filter resize $img_width $img_height;
image_filter_buffer 1M;
image_filter_jpeg_quality 75;
allow 127.0.0.0/8;
deny all;
log_format imageresize '$host $request_uri $request_filename ${img_width}x${img_height} [$time_local]';
access_log /var/log/nginx/resize.access_log imageresize;
}
-
if ... break; rewrites the url without passing control to the new url handler.
- If you want to store images on a folder that is not named the same as the uri, you need to change
proxy_store accordingly and probably set some variable to the basename of the file.
- Back-proxy is a hack, I should probably patch
image_filter when i have the time.
Performance notes
Image resize is heavy on CPU, so use caching/proxy_store whenever possible. However, due to Nginx async nature Nginx will wait for the resize to complete before serving other requests, so use a relatively large number of child processes.
Remember: this is not production grade, it's much better to have a separate process do the resize via FastCGI.