画像変換は EC2 に導入した ngx_small_light で行い、画像の実体は Nginx のプロキシ機能を使って WEB ホスティングした S3 から取得する構成です(EC2 はリバースプロキシ&画像変換サーバとして動作する)。既に画像を S3 の WEB ホスティングで配信しているサービスであれば、リバースプロキシ&画像変換サーバを S3 の前段に置くことで画像変換機能を付与することが出来ます。
簡単に試してみたので、本投稿はその手順のメモです。
ngx_small_light の概要はこちらのスライドが分かりやすかったです。
⇒ 実践ngx_small_light入門 by Tatsuhiko Kubo【Speaker Deck】
環境構築の手順
EC2 の用意
今回は クイックスタート
の一番上にある、このマシンイメージ(AMI)を利用しました。OS は Amazon Linux
になります。
インスタンスの作成手順については、ここでは割愛します。
Nginx のインストール
Nginx は yum
でなくソースからインストールします(後で ngx_small_light
を組み込むので)。
Nginx 用のユーザ/グループを作成
$ sudo useradd --shell /sbin/nologin nginx
/etc/passwd
と/etc/group
にnginx
ユーザ/グループが追加されているはずです。
Nginx のビルドで必要となるソフトウェアの導入
$ sudo yum install -y gcc
$ sudo yum install -y pcre pcre-devel
$ sudo yum install -y zlib zlib-devel
自分の場合は上記のもので大丈夫でしたが、環境によって異なると思うので、Nginx ビルド時のエラーメッセージに従って必要なものを導入してください。ちなみに今回は SSL は利用しない想定なので
openssl
openssl-devel
は導入していません。
Nginx パッケージの取得とインストール
http://nginx.org/en/download.html の Stable version
のバージョンを調べます。執筆時点では 1.8
なので、それをインストールします。適当なディレクトリで作業します(今回は~/work
)。
$ cd ~
$ mkdir work
$ cd work
$ wget http://nginx.org/download/nginx-1.8.0.tar.gz
$ tar zxvf nginx-1.8.0.tar.gz
$ cd nginx-1.8.0
$ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
configure
に成功すると次のようにサマリーが表示されます。
コンパイルとインストールを行います。
$ make
$ sudo make install
Nginx の起動設定
/etc/init.d/nginx
を新規に作成します。
$ sudo touch /etc/init.d/nginx
$ sudo chmod +x /etc/init.d/nginx
上記の /etc/init.d/nginx
を vi
等で開き、https://www.nginx.com/resources/wiki/start/topics/examples/redhatnginxinit/ の内容をコピーして貼り付けた後、今回の環境に合わせて次のように編集します。
...
-nginx="/usr/sbin/nginx"
+nginx="/usr/local/nginx/sbin/nginx"
...
-NGINX_CONF_FILE="/etc/nginx/nginx.conf"
+NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
...
Nginx のチューニング
ngx_small_light
向けにやっておいた方が良さそうなので一応やっておきます。/etc/sysconfig/nginx
を新規に作成します。
$ sudo touch /etc/sysconfig/nginx
次の一文を書きます。
export OMP_NUM_THREADS=1
ワーカープロセス数も増やしておきます。
-worker_processes 1
+worker_processes 10
Nginx を起動してみる
$ sudo service nginx start
ブラウザで EC2 のパブリックIPにアクセスしてみて、次のように表示されればOKです。
ちなみに Nginx の再起動は $ sudo service nginx restart
、停止は $ sudo service nginx stop
、設定ファイルの修正内容の反映は $ sudo service nginx reload
で実行できます。
Nginx の自動起動設定
EC2 サーバの立ち上げ時に自動で Nginx も立ち上がるようにしておきます。
$ sudo chkconfig nginx on
以上で Nginx のインストールは完了です。
後に説明する
ngx_small_light
のインスール時に Nignx を再ビルドすることになりますが、いちおう Nginx 単体の動作確認をした感じです。
ちなみに Nginx のドキュメントルートや設定ファイル類、ログは /usr/local/nginx
配下にまとまっています。
ngx_small_light のインストール
ngx_small_light は画像変換用の Nginx モジュールです。GitHub で公開されています。
⇒ https://github.com/cubicdaiya/ngx_small_light
執筆時点の最新バージョンは v0.6.11
で、今回はこの最新バージョンを利用しました。
今回は ImageMagic
だけを使う想定なので Imlib2
GD
は導入しませんが、必要あらば上記 Github の README や Wiki 、この投稿の最後に記載した参考記事を元に導入してください。
ngx_small_light の取得とセットアップ
適当なディレクトリで作業します(今回は~/work
)。
$ cd ~/work
$ sudo yum install -y git
$ git clone https://github.com/cubicdaiya/ngx_small_light.git
$ sudo yum install -y ImageMagick ImageMagick-devel
$ cd ngx_small_light
$ ./setup
Git
とImageMagic
も導入していますが、既に環境に入っていればこの手順は不要です。また今回はImageMagic
だけを使う想定なのでImlib2
GD
は導入していません。
setup
が成功すると config is generated.
と表示されます。
Nginx の再ビルド・再インストール
$ cd ~/work/nginx-1.8.0
$ ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --add-module=/home/ec2-user/work/ngx_small_light/
$ make
$ sudo make install
/home/ec2-user/work/ngx_small_light/
のところはngx_small_light
をセットアップしたディレクリを指定します。環境に合わせて変更してください。
上記で問題なければ Nginx を再起動します。
$ sudo service nginx restart
ngx_samll_light を使って S3 の画像を変換してみる
今回は単純に jpeg
画像を縮小してみます。
ngx_small_light
の詳しい使い方は Wiki を見ると良いかと思います。
WEB ホスティングした S3 に適当な画像を置きます。今回は次のような 1000 × 667
px の画像を用意しました。
S3 上のURLは次のようになっているものとします。
http://hoge.s3-us-west-2.amazonaws.com/photo/cat.jpg
/usr/local/nginx/conf/nginx.conf
を開き jpeg
画像へのリクエストの場合は横幅 300
px に縮小する設定を書いてみます。
http {
# ...
server {
# ...
+ small_light on;
+ small_light_getparam_mode on;
+ small_light_pattern_define option dw=300,jpeghint=y;
+
+ location ~ ^/(photo/.+)$ {
+ set $path $1;
+
+ proxy_pass http://hoge.s3-us-west-2.amazonaws.com;
+
+ # jpeg 画像の場合のみ変換
+ if ($path ~ ".+\.jpg$") {
+ rewrite .* /$path?p=option break;
+ }
+
+ # jpeg 画像でない場合はそのまま流す
+ rewrite .* /$path break;
+ }
# ...
修正したら Nginx をリロードします。
$ sudo service nginx reload
ブラウザで EC2 のパブリックIPにアクセスしてみます。次のように縮小されました。
注意
ngx_small_light
のクエリで変換オプションを指定するモード(small_light_getparam_mode on
)を利用する場合、この Nginx の server
で受ける全てのHTTPリクエストが画像である必要があります(そうでない場合は HTTP 415 エラー《Unsupported Media Type》となりました)。
おわりに
ngx_small_light
は画像の縮小だけでなく、画像の合成ができたり、画像を WebP 形式に変換できたりするようなので、モバイル向け画像変換として応用範囲が広そうです。今後もいろいろ試してみようと思いました。
実運用では画像変換の負荷が心配なので、さらに前段に CloudFront や Akamai のような CDN を利用するのが良いかと思います。