Nginxにngx_small_lightモジュールを入れて画像の自動リサイズ処理をする

ngx_small_lightについて

ngx_small_lightモジュールの概要

ngx_small_lightはNginxにモジュールとして追加できる機能になります。

主に画像のリサイズやクオリティー値(圧縮度)の調整、画像の切り取りなどがngx_small_lightにて行なえますが、その他にもまだまだ行える事があります。

導入メリット

  • サーバにアップロードする画像にリサイズ調整を加える必要がない
  • ngx_small_lightでクオリティー値(圧縮度)の調整ができるため、Webブラウザのダウンロード時間が短縮され、ブラウザ表示が速くなる

デメリット・リスク

  • オリジナル画像(ngx_small_lightでリサイズする前の画像)が大きい場合、サーバの容量を圧迫する可能性がある
  • ngx_small_lightで画像をリサイズしたり、クオリティー値の調整をしたりするため、ngx_small_lightを利用しない時に比べて、サーバに負荷がかかる

今回紹介する内容

  • Nginxをソースからインストール
  • ngx_small_lightモジュールの導入
  • ngx_small_lightの設定
    • パターン指定で画像をリサイズ
    • クオリティー値の設定

導入環境

cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

Nginxをソースからインストール

ではさっそくやってみます。

Nginxのインストールの前に必要な諸々

# Nginx用のユーザ/グループを作成
useradd --shell /sbin/nologin nginx

# Nginxのビルドで必要となるソフトウェアの導入
sudo yum install gcc \
pcre \
pcre-devel \
zlib \
zlib-devel \
openssl-devel \
libxslt-devel \
gd-devel \
perl-ExtUtils-Embed

# 起動スクリプトの配置
vim /usr/lib/systemd/system/nginx.service

# nginx.serviceの中身
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/etc/nginx/logs/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/conf/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

ngx_small_lightのインストール

cd /usr/local/src

# コンパイルに必要なプログラムのインストール
yum install \
flex \
gcc \
redhat-rpm-config \
strace \
rpm-build \
make \
pkgconfig \
gettext \
automake \
strace \
gdb \
bison \
libtool \
autoconf \
gcc-c++ \
binutils

# ngx_small_light 系パッケージのインストール
yum install ImageMagick ImageMagick-devel

yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/imlib2-1.4.2-5.el6.x86_64.rpm \
http://dl.fedoraproject.org/pub/epel/6/x86_64/imlib2-devel-1.4.2-5.el6.x86_64.rpm

# ngx_small_light をダウンロード
git clone https://github.com/cubicdaiya/ngx_small_light.git
cd ngx_small_light/
./setup --with-imlib2 --with-gd

# ngx_small_lightのパスを設定
ngx_small_light=`pwd`

Nginxパッケージの取得とインストール

# ディレクトリ移動
cd /usr/local/src

# nginx-1.12.0 ダウンロード
wget http://nginx.org/download/nginx-1.12.0.tar.gz

# nginx-1.12.0 解凍
sudo tar zxvf nginx-1.12.0.tar.gz

# ディレクトリ移動
cd ./nginx-1.12.0

# configureの設定
sudo ./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_perl_module=dynamic \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-http_v2_module \
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' \
--with-ld-opt=-Wl,-E \
--add-module=$ngx_small_light

sudo make && sudo make install

# Nginxのバージョン、ngx_small_lightモジュールの確認
nginx -V
nginx version: nginx/1.12.0
--add-module=/usr/local/src/ngx_small_light

# Nginx起動
systemctl start nginx

# Nginx停止
systemctl stop nginx

# Nginx自動起動
systemctl enable nginx

ngx_small_lightの設定

今回Nginxの設定紹介は省いております。

nginx.conf

http {
	include       mime.types;
	default_type  application/octet-stream;

	# その他設定は割愛しています

	upstream image-resize {
		server 127.0.0.1:40001;
   }

   server {
		listen       80;
		server_name  localhost;

		# ngx_small_light 用の URL を組み立てる
		location ~ /img/([^\.]+)\.jpg$  {
			log_not_found   off;

			set $file_path $1.jpg;

			set $pattern l;
			if ($args ~* "(?:^|&;)size=(m|s)") {
				set $pattern $1;
			}

			# 内部通信のため少しでも速くなるようにhttp通信を利用
			proxy_pass http://image-resize/small_light(p=$pattern)/img/$file_path;
			break;
		}
	}

	# image-resize
	server {
		listen 127.0.0.1:40001;
		server_name image-resize;

		# ngx_small_light を有効にする
		small_light on;

		# パターン設定
		small_light_pattern_define l dw=800,da=l,q=75,e=imagemagick,jpeghint=y;
		small_light_pattern_define m dw=500,da=l,q=50,e=imagemagick,jpeghint=y;
		small_light_pattern_define s dw=300,da=l,q=30,e=imagemagick,jpeghint=y;

		location ~ small_light[^/]*/img/(.+)$ {
		log_not_found   off;

		set $file $1;
		rewrite ^ /$file;
	}

	location ~ /img/  {
		log_not_found   off;

		alias /img/;
		break;
	}		
}

small_light_pattern_define

これは画像変換するパターンを設定する時に利用する記述です。

今回設定したパターンは下記になります。

  • パターン:l
    • 縦横比を維持して画像幅を800pxに変換、クオリティー値を75に設定し、画像エンジンにImagemagickを利用し、jpeg画像の変換を速くしています。
    • http://ドメイン/img/****.jpg
    • http://ドメイン/img/****.jpg?size=l
  • パターン:m
    • 縦横比を維持して画像幅を500pxに変換、クオリティー値を50に設定し、画像エンジンにImagemagickを利用し、jpeg画像の変換を速くしています。
    • http://ドメイン/img/****.jpg?size=m
  • パターン:s
    • 縦横比を維持して画像幅を300pxに変換、クオリティー値を30に設定し、画像エンジンにImagemagickを利用し、jpeg画像の変換を速くしています。
    • http://ドメイン/img/****.jpg?size=s

その他の設定値などは正式なREADME.mdを参照ください。

https://github.com/cubicdaiya/ngx_small_light

最後に

後はNginxを再起動してブラウザでアクセスして表示をご確認ください。

今回なぜパターンを決めて利用するようにしたかというと、クエリーにdw,dyなどを常に付与するようにしてもっと汎用性のある利用方法もあるのですが、デメリットにも書きましたがngx_small_lightの画像変換処理が走るためサーバの負荷が高くなります。

ですが今回のようにパターンを設定し、画像をproxy_cacheなどでキャッシュすれば、ある程度の画像リサイズや変換の恩恵も受けつつ、キャッシュによってサーバへの負荷も下げられるためパターン指定を利用するようにしました。

スペックのいいサーバを利用されている方などはパターン指定を行わず利用すれば、cssなどから画像サイズ指定を全て取り払うことも可能になります。

ではではこれにてngx_small_lightモジュールの導入は完了になります。