Skip to content

Instantly share code, notes, and snippets.

@phpdude
Last active February 28, 2024 04:36
Show Gist options
  • Save phpdude/1451684 to your computer and use it in GitHub Desktop.
Save phpdude/1451684 to your computer and use it in GitHub Desktop.
Nginx image filter + caching of results.
Nginx image filter + caching of results.
Supports dynamic thumbnails images sizes processing + caching results, simple to use.
Awesome!!!
location /resize {
alias /tmp/nginx/resize;
set $width 150;
set $height 100;
set $dimens "";
if ($uri ~* "^/resize_(\d+)x(\d+)/(.*)" ) {
set $width $1;
set $height $2;
set $image_path $3;
set $dimens "_$1x$2";
}
if ($uri ~* "^/resize/(.*)" ) {
set $image_path $1;
}
set $image_uri image_resize/$image_path?width=$width&height=$height;
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8080/$image_uri;
break;
}
proxy_store /tmp/nginx/resize$dimens/$image_path;
proxy_store_access user:rw group:rw all:r;
proxy_temp_path /tmp/images;
proxy_set_header Host $host;
}
location /image_resize {
alias /path/to/media/;
image_filter resize $arg_width $arg_height;
image_filter_jpeg_quality 75;
allow 127.0.0.0/8;
deny all;
}
@imazine
Copy link

imazine commented Feb 15, 2013

It's Awesome!!!

Thanks :D

@boypt
Copy link

boypt commented Jun 27, 2013

it's better to add 'internal;' directive in the /image_resize location, instead of using allow/deny.

@fredpalmer
Copy link

I tried internal and had to revert back to allow/deny

Update

I figured out why internal won't work in this situation from this:

Internal requests are the following:

requests redirected by the instruction error_page
subrequests created by the command include virtual of the "ngx_http_ssi_module" module
requests changed by the instruction rewrite of the "ngx_http_rewrite_module" module

http://wiki.nginx.org/HttpCoreModule#internal

@fredpalmer
Copy link

I also added some flavor and made a complete example of how to use some of the other commands as well for essentially what is a stand-alone server config whose sole purpose is to dynamically resize images from remote sources. Hope this helps the community at large:

https://github.com/fredpalmer/dimwit/

@smowtion
Copy link

Have an error
nginx: [emerg] unknown directive "image_filter" in /usr/local/nginx/conf/conf.d/virtual.conf:42

@tarikjn
Copy link

tarikjn commented Mar 28, 2014

@fredpalmer looks like your version has some issues with caching, doing subsequent request on the same image still requires a noticeable load time, any idea what this could be?

@fredpalmer
Copy link

@tarikjn Made a couple of changes recently - maybe try the new version. Handles redirects now. Could be a factor of image size?

@fredpalmer
Copy link

@Thomanphan You don't have http://nginx.org/en/docs/http/ngx_http_image_filter_module.html installed most likely. You'll probably need to compile it and/or install a pre-built version that includes it like the Ubuntu package:

sudo apt-get install nginx-extras-dbg

@Zagrebelin
Copy link

location ~ ^/(\d+|-)x(\d+|-)/(.*\.(?:jpg|gif|png))$ {
alias /path/to/images/$3;
image_filter resize $1 $2;
}

From here http://habrahabr.ru/post/94435/#comment_2913463.

@BaseMax
Copy link

BaseMax commented Jan 11, 2015

Is it possible to cache the resized images without proxy_pass ? for internal image source?

@phpdude
Copy link
Author

phpdude commented Apr 11, 2015

Wow!

I didn't receive any notifications about this gist. I really impressed to publish so popular solution.

@asadpakistani
Copy link

How to prevent resource abuse or DDOS on this?

@extead
Copy link

extead commented Jun 29, 2016

Hi! I use the following config:

 location /pics {
          alias /var/www/pics;
          set $width 500;
          set $height 500;
          set $dimens "";
​
          if ($uri ~* "^/pics_(\d+)x(\d+)/(.*)" ) {
                  set $width  $1;
                  set $height $2;
                  set $image_path $3;
                  set $demins "$1x$2";
          }
          if ($uri ~* "^/pics/(.*)" ) {
                  set $image_path $1;
          }
          set $image_uri image_resize/$image_path?width=$width&height=$height;
​
          if (!-f $request_filename) {
                  proxy_pass http://192.168.1.1/$image_uri;
                  break;
          }
          proxy_store          /var/www/pics/$demins/$image_path;
          proxy_store_access   user:rw  group:rw  all:r;
          proxy_temp_path      /tmp/images;
          proxy_set_header     Host $host;
​
  }
​
  location /image_resize {
          alias /var/www/pics;
          image_filter resize $arg_width $arg_height;
          image_filter_jpeg_quality 75;
          allow 127.0.0.0/8;
          allow 192.168.1.1/32;
          deny all;
  }

Resizing works. But cache not. The directory /var/www/pics/$demins/$image_path isn't created =(

@24HOURSMEDIA
Copy link

24HOURSMEDIA commented Feb 25, 2017

Q: How to prevent resource abuse or DDOS on this?

  • I think you should set the width and height parameters in the url, i.e. image_resize/100x100/{image_path}

  • and either parse the image width and height or make specific locations for desired image sizes

  • And limit the available width/heights so people cannot enter width=10000 etc..

  • In combination with caching this should provide some protection

  • Configure nginx to limit the max request rate for an ipfor the image endpoints, i.e. @see https://www.nginx.com/blog/mitigating-ddos-attacks-with-nginx-and-nginx-plus/

@bienkma
Copy link

bienkma commented Jan 12, 2018

Howto remove ratio when i using image_filter resize w_size h_size? I think sometimes it must specific exactly width and hieght of picture.

@cadavre
Copy link

cadavre commented Feb 18, 2020

There is a typo since version 1. :)

set $dimens "";
      ^

set $demins "$1x$2";
      ^

proxy_store /var/www/pics/$demins/$image_path;
                            ^

Should be $dimens everywhere I believe.

@phpdude
Copy link
Author

phpdude commented Feb 18, 2020

oh, lol! @cadavre thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment