How To Resize On The Fly & Cache Images in Nginx

Nginx provides the image_filter module for the dynamic image resizing. This Nginx configuration will allow for requests such as http://server.com/images/1024/river.jpg - this image will be resized to 1024 pixels wide and compressed using the quality value of 95. Requests asking for images larger than 20 megabytes (before resizing) will be resized.

server {
  server_name server.com;

  location ~ "^/images/(?<width>\d+)/(?<image>.+)$" {
    alias /srv/www/images/$image;
    image_filter resize $width -;
    image_filter_jpeg_quality 95;
    image_filter_buffer 20M;
  }
}

This configuration triggers the resizing on every request, even if the request repeats itself. There is a need for caching. This requires a separate server block in Nginx: first, internal for the actual resizing and second, public that redirects the requests to the first one, but it also caches them when necessary.

server {
  server_name localhost;
  listen 8888;

  location ~ "^/images/(?<width>\d+)/(?<image>.+)$" {
    alias /srv/www/images/$image;
    image_filter resize $width -;
    image_filter_jpeg_quality 95;
    image_filter_buffer 20M;
  }
}

proxy_cache_path /srv/images-cache/ levels=1:2 keys_zone=images:10m inactive=24h max_size=100m;

server {
  server_name server.com;

  location ~ "^/images/(?<width>(768|1024))/(?<image>.+)$" {
    proxy_pass http://localhost:8888/images/$width/$image;
    proxy_cache images;
    proxy_cache_valid 200 24h;
  }

  location /images {
    # You need to explicitly define DNS resolution when using
    # variables in the proxy_pass directive. This trick resolves that.
    proxy_pass http://localhost:8888/;
  }
}