Last active
November 8, 2019 11:00
-
-
Save Apkawa/1deada27a09481747fa6a8b9343901a0 to your computer and use it in GitHub Desktop.
Nginx resize with invalidation after change source image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function etag_resize (r) { | |
function done (r2) { | |
// Extract etag header | |
var source_etag = r2.headersOut.etag | |
// Pass variables from location | |
var width = r.variables.width | |
var height = r.variables.height | |
var image_path = r.variables.image_path | |
var convert_path = r.variables.convert_path || '/_ei/' | |
// construct resize with cache url | |
var path = `${convert_path}${image_path}?width=${width}&height=${height}&source_etag=${source_etag}` | |
r.internalRedirect(path) | |
} | |
r.subrequest(r.variables.image_path, { method: 'HEAD' }, done) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# We need njs and image_filter module. Also avaiable on docker image `nginx:1.17` | |
load_module /etc/nginx/modules/ngx_http_image_filter_module.so; | |
load_module /etc/nginx/modules/ngx_http_js_module.so; | |
http { | |
# .. other setting default | |
proxy_cache_path /nginx-data/resize/ levels=1:2 keys_zone=resize_images:512m inactive=30d max_size=10G; | |
# Important! | |
js_include etag_resize.js; | |
server { | |
listen 80; | |
server_name _; | |
location /media { | |
# Etag must be enabled! | |
etag on; | |
alias /public/media/; | |
# TODO cache | |
expires 1y; | |
# access_log off; | |
add_header Vary Accept-Encoding; | |
add_header Cache-Control public; | |
} | |
location ~* '^/i/(\d+)x(\d+)/(.*)$' { | |
# https://example.org/i/<width>x<height>/path/to/image.png | |
set $width $1; | |
set $height $2; | |
set $image_path /$3; | |
js_content etag_resize; | |
} | |
location ~* '^/i/w(\d+)/(.*)$' { | |
# https://example.org/i/w<width>/path/to/image.png | |
set $width $1; | |
set $height "-"; | |
set $image_path /$2; | |
js_content etag_resize; | |
} | |
location ~* '^/i/h(\d+)/(.*)$' { | |
# https://example.org/i/w<width>/path/to/image.png | |
set $width "-"; | |
set $height $1; | |
set $image_path /$2; | |
js_content etag_resize; | |
} | |
location ~* '^/i/(.*)$' { | |
# https://example.org/i/path/to/image.png | |
set $width 100; | |
set $height 100; | |
set $image_path /$1; | |
js_content etag_resize; | |
} | |
location /_ei/ { | |
# Based by https://gist.github.com/phpdude/1451684 | |
# Magic from | |
# https://stackoverflow.com/questions/28684300/nginx-pass-proxy-subdirectory-without-url-decoding/37584637 | |
rewrite ^ $request_uri; | |
rewrite ^/_ei/(.*) $1 break; | |
# End magic | |
root /nginx-data/resize/; | |
set $width $arg_width; | |
set $height $arg_height; | |
set $source_etag $arg_source_etag; | |
if ($source_etag ~* '^"(.*)"$') { | |
set $source_etag $1; | |
} | |
if ($uri ~* "^/_ei/(.*)" ) { | |
set $image_path $1; | |
} | |
if ($image_path ~* "^.*\.(.*)$") { | |
set $ext $1; | |
} | |
set $image_uri __resize/$image_path?width=$width&height=$height; | |
set $resize_status 'no'; | |
set $image_store_path "$image_path/$source_etag/${width}x${height}.$ext"; | |
set $abs_image_store_path "/nginx-data/resize$image_store_path"; | |
if (!-f $abs_image_store_path) { | |
proxy_pass http://127.0.0.1:80/$image_uri; | |
set $resize_status 'yes'; | |
break; | |
} | |
proxy_store $abs_image_store_path; | |
proxy_store_access user:rw group:rw all:r; | |
proxy_temp_path /tmp/images; | |
# For debug | |
add_header X-Filename $abs_image_store_path; | |
add_header X-Resize-Status $resize_status; | |
add_header X-Source-Etag $source_tag; | |
expires 1y; | |
access_log off; | |
add_header Vary Accept-Encoding; | |
add_header Cache-Control public; | |
rewrite ^(.*)$ $image_store_path break; | |
} | |
location /__resize/ { | |
alias /public/; | |
image_filter_buffer 50M; | |
image_filter resize $arg_width $arg_height; | |
image_filter_jpeg_quality 75; | |
allow 127.0.0.0/8; | |
deny all; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment