1. トップ
  2. WEBサイト高速化のためにアップロード画像をnginxで軽量化&キャッシュ化した

iphoneやらデジカメで撮影した写真バンバンアップロードしてるけど、サイトの表示遅いな〜〜〜〜

でもいちいちPCで軽くしてからアップロードするのめんどくさいな〜〜〜

phpで実装するのもめんどくさいな〜〜〜

と思ったのでやりました

忙しい人向け

nginxのimage_filterモジュール使った

公式リファレンス

 

<nginxのconf>

location ~ ^/resize/(?\d+)x(?\d+)/(?.*)$ {
    proxy_cache CACHE_ZONE_NAME;
    proxy_cache_key $scheme//$host$request_uri$is_args$args;
    proxy_cache_valid  200 7d;
    proxy_cache_valid  404 1m;
    proxy_cache_valid  500 5s;

    image_filter_buffer 50M;
    image_filter resize $width $height;
    image_filter_jpeg_quality 90;

    rewrite ^/resize/(\d+)x(\d+)\_(\d+)/(.*)$ /$4 break;
    proxy_pass http://backend;
}

<cacheのconf>

proxy_cache_path      /var/cache/nginx/hoge levels=1:2 keys_zone=CACHE_ZONE_NAME:15m inactive=7d max_size=10000m;

 

<imgタグ>

<img src=”/resize/400x400/hoge.jpg”>

ゆっくりできる人向け

image_filterとは?

The ngx_http_image_filter_module module (0.7.54+) is a filter that transforms images in JPEG, GIF, PNG, and WebP formats.

This module is not built by default, it should be enabled with the --with-http_image_filter_module configuration parameter.

公式リファレンス

「画像をリサイズしたり切り取ったりいろいろできるよ、このモジュールはデフォルトでは入っていないから入れてね」

と言っているらしい

image_filterを使えるようにする

公式にもあったとおりimage_filterモジュールを使うので、モジュール(またはnginx-full)のインストールが必要。

さらにnginx.confの上の方でモジュールの読み込みが必要。

 

モジュール読み込み記述例)

load_module /usr/local/libexec/nginx/ngx_http_image_filter_module.so;

 

記述したらnginx reloadもしくはnginx restartで有効になる

image_filterの設定

ぼくはこんな感じに

location ~ ^/resize/(?\d+)x(?\d+)/(?.*)$ {
    ## <=== キャッシュの設定
    proxy_cache CACHE_ZONE_NAME;
    proxy_cache_key $scheme//$host$request_uri$is_args$args;
    proxy_cache_valid  200 7d;
    proxy_cache_valid  404 1m;
    proxy_cache_valid  500 5s;
    ## キャッシュの設定 ===>

    image_filter_buffer 50M;
    image_filter resize $width $height;
    image_filter_jpeg_quality 90;

    rewrite ^/resize/(\d+)x(\d+)\_(\d+)/(.*)$ /$4 break;
    proxy_pass http://backend;
}

設定内容の説明は

location:「/resize/数字1x数字2/hogehoge.jpg」みたいなURLのときここのルールを適用しますよ
image_filter_buffer:大きい画像も処理できるようにしますよ
image_filter resize:幅を「数字1」高さを「数字2」にしてくださいね
image_filter_jpeg_quality:画像の品質は少し落としていいですよ

という感じ

 

あとはHTML側で画像表示の部分のURLを

<img src=”/hogehoge.jpg”>
から
<img src=”/resize/100x100/hogehoge.jpg”>

に変更するだけ

キャッシュ化の話

公式リファレンス

 

location ~ ^/resize/(?\d+)x(?\d+)/(?.*)$ {
    ## <=== キャッシュの設定
    proxy_cache CACHE_ZONE_NAME;
    proxy_cache_key $scheme//$host$request_uri$is_args$args;
    proxy_cache_valid  200 7d;
    proxy_cache_valid  404 1m;
    proxy_cache_valid  500 5s;
    ## キャッシュの設定 ===>

    image_filter_buffer 50M;
    image_filter resize $width $height;
    image_filter_jpeg_quality 90;

    rewrite ^/resize/(\d+)x(\d+)\_(\d+)/(.*)$ /$4 break;
    proxy_pass http://backend;
}

上述した設定内容、コメント「キャッシュの設定」で囲っている部分。

これだけだとだめで、このconfと同じディレクトリに

 

<cache.conf>

proxy_cache_path      /var/cache/nginx/hoge levels=1:2 keys_zone=CACHE_ZONE_NAME:15m inactive=7d max_size=10000m;

こんな感じのファイルを作ればおけー

これで無事に画像の軽量化&キャッシュ化ができました、というお話でした