画像の動的リサイズを行うDocker Container
Google Cloud Storage にアップロードした画像をNginxのimage filter moduleを使って動的リサイズするDocker Containerを作った記録です。
前提
以下のようなモチベーションや要件で行いました
- アップロード済みの画像サイズを自由に変更したい
- Google Cloud Storage にアップロードしている
- 低コストで試せると良い
- 元画像のuriをあまり変えずにクエリストリングでやりたい
- キャッシュも出来ると良い
選んだ方法
Nginxでプロキシする。
Nginxのimage filter moduleを使ってリサイズする。
割とやり尽くされているであろう方法の記録になります。
概要
# ↓キャッシュ
proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=resized:64m max_size=20000m inactive=1d;
server {
listen 80;
access_log /var/log/nginx/proxy.log;
location / {
proxy_pass "http://127.0.0.1:9001";
proxy_cache resized;
proxy_cache_valid 200 302 24h;
proxy_cache_valid 404 1m;
# expire time for browser
expires 1d;
}
}
# ↓リサイズ
limit_req_zone "1" zone=2persec:32k rate=2r/s;
server {
listen 9001;
allow 127.0.0.1;
deny all;
limit_req zone=2persec burst=10;
access_log /var/log/nginx/resizer.log; server_name storage.googleapis.com;
resolver 8.8.8.8 8.8.4.4; location ~ /(.*)/original {
internal;
proxy_pass https://storage.googleapis.com/your-project/$path;
} location ~ /(.*)/resize {
internal;
proxy_pass https://storage.googleapis.com/your-project/$path;
image_filter resize $width $height;
image_filter_jpeg_quality $quality;
image_filter_buffer 100M;
error_page 415 = @empty;
} location @empty {
empty_gif;
} location ~ /(.*)$ {
set $path $1; if ($args = "") {
rewrite ^ /(.*)/original last;
} set $width "-";
set $height "-";
set $quality 100; if ($arg_w ~ ([0-9]+)) {
set $width $1;
}
if ($arg_h ~ ([0-9]+)) {
set $height $1;
}
if ($arg_q ~ (100|[1-9][0-9]|[1-9])) {
set $quality $1;
} rewrite ^ /(.*)/resize last;
}
}
例えば以下の画像を取得したいときに
https://storage.googleapis.com/your-project/your/file/name.jpg
このようにGETすると元の画像がそのまま取得できる。
http://localhost:8080/your/file/name.jpg
このようにquery stringをつけると500 x 500でjpeg_quality70でリサイズされた画像が取得できる。
http://localhost:8080/your/file/name.jpg?w=500&h=500&q=70
Github Repository
シンプルなので詳細は是非実際のコードをご覧ください。
そのまま使えるようになっているはずです。
課題
比較的簡単にこのような機能が作れる一方でimgixのようなSaaSも存在する。
そしてそれらを使っている人が多いように思えた。
つまりこういった方法での画像加工には何かしら課題や困りごとが存在するのだろう。
今は自分にはどんな課題や困りごとが起こりうるのかがあまり想像がついていない。
Nginxも不慣れなため正しく使えている自信がない。
ご助言いただければ幸いです。
参考やその他の解決法
参考にした記事や画像の動的リサイズにおけるそのその他の解決方法も記載しておく。
きっとそのうち別の方法に乗り換えるだろう。