nginxにngx_mrubyをインストールする

この記事は [mod_mruby ngx_mruby Advent Calendar 2014](http://qiita.com/advent-calendar/2014/mod-ngx-mruby) 11 日目の記事です。

@takeswimです。福岡のゲーム会社でネットワークに関する諸々の開発をしています。

@matsumotoryさんがnginxへのngx_mrubyインストールについて投稿リクエストされておりまして、実は時を同じくして久しぶりにnginx+ngx_mrubyのインストール作業をしていまして、一連の作業を元にまとめてみました。

今回はnginx1.7.8(投稿当時最新版)に対しngx_mrubyを組み込む手順について解説したいと思います。

環境はGoogle Cloud Platformから払い出しました。

* OSはCentOS6.6
* http接続許可
* それ以外はデフォルト

で用意しています。

最初にオチを書いておきますと、私がこの投稿を書きながら知ったbuild.shを使用したインストールがすごく楽でお薦めです。この手法は投稿の終盤に説明しています。
またnginxへのモジュールの組み込みが「nginxにngx_mrubyを組み込む」というより「ngx_mrubyつきnginxを作る」と言った方が作業内容としては近く、タイトルとやっていることにズレがあることご容赦ください。

# 準備編
## nginxにモジュールを組み込むには?
nginxにモジュールを追加する場合はnginxをmakeしなおす必要があります。
nginx側configureの`--add-module`オプションを使い、以下のように追加設定します。

```
$ ./configure --add-module=[モジュールの存在するpath]
```

## nginxにngx_mrubyを組み込むには?
ですので、nginxにngx_mrubyを組み込むには

* nginx側configureの`--add-module`でngx_mrubyの設定を加えnginxをmakeする

ということになります。
ngx_mrubyの組み込み方法は他にも

* ngx_mruby側のmakeでngx_mrubyつきnginxを作る
* ngx_mruby側のbuild.shでngx_mrubyつきnginxを作る

という手法があり、今回はそれぞれ試してみようと思います。

## 開発環境の準備
最初の環境が本当にまっさらでしたので、まずはgit,gccから…

```
$ sudo yum install git gcc -y
```

## nginxをmakeする
nginxマスターには釈迦に説法で申し訳ありませんが念のため…

```
code:sh
$ cd ~
$ wget http://nginx.org/download/nginx-1.7.8.tar.gz
$ tar zxvf ./nginx-1.7.8.tar.gz
$ cd nginx-1.7.8
$ ./configure --prefix=/usr/local/nginx/
$ make
$ sudo make install
```

make途中でPCREとzlibが必要になり、適宜yumでインストールしています。

```
$ sudo yum install pcre-devel zlib-devel -y
```

インストールまで完了したら、一応起動して確認しておきましょう。

```
$ sudo /usr/local/nginx/sbin/nginx
```
ブラウザ等で
http://localhost/
でnginxインストール直後のデフォルト画面が出てくるか確認します。

# ngx_mruby組み込み編
##ngx_mrubyをmakeする
ngx_mrubyを準備します。

```
$ cd ~
$ git clone git://github.com/matsumoto-r/ngx_mruby.git
$ cd ngx_mruby/
$ git submodule init
$ git submodule update
```
ngx_mrubyにはsubmoduleとしてmrubyが関連付けされていますので、submoduleに関する対応が必要です。
そのうえでconfigure & makeします。

```
$ ./configure --with-ngx-src-root=/home/takeswim/nginx-1.7.8
```

`--with-ngx-src-root`設定でnginxのソースパスを設定します。これが無いとエラーになります。

```
$ make build_mruby
$ make generate_gems_config

```

ngx_mrubyのmakeにはrakeが必要です。
古いrake(少なくともyumでインストールできるruby1.8.7)だと失敗するようで、結局最新版のrubyをソースインストールしました。

```
$ cd ~
$ wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.5.tar.gz
$ tar zxvf ruby-2.1.5.tar.gz
$ cd ruby-2.1.5
$ ./configure & make & sudo make install
```

またmake途中で以下のインストールをしました。

* bison
  mrubyのビルドツールに必要。
`$ sudo yum install bison -y`

* openssl
  mruby-digestに必要。
`$ sudo yum install openssl-devel -y`

* redis
* hiredis
mruby-redisに必要。今回の環境ではredis・hiredisともソースインストールしました。

```
$ cd ~
$ wget http://download.redis.io/releases/redis-2.8.18.tar.gz
$ tar zxvf redis-2.8.18.tar.gz
$ cd redis-2.8.18
$ make & sudo make install
$ cd ~
$ git clone https://github.com/redis/hiredis.git
$ cd hiredis
$ make & sudo make install
```

ちなみに当環境ではhiredisの共有ライブラリが認識されませんでした。
`$ /etc/ld.so.conf.d/hiredis.conf`でライブラリpath(`/usr/local/lib/`)を追加して`$ sudo ldconfig`実行します。

こういった感じで適宜ライブラリをインストールしていき、ngx_mrubyのmakeが完了します。

## add-moduleでngx_mrubyの設定を加えnginxをmakeする

ngx_mrubyの準備が済んだところで、nginxにngx_mrubyを組み込みます。

既に先ほどの手順でnginxはmake済ですし、nginxを運用している人ならnginxのソースは既に手元にあるかと思います。

nginxのソースパスに移動し、configureの`--add-module`オプションでngx_mruby組み込み設定します。
もちろんnginxの他のオプション設定も可能です。

```
$ cd ~/nginx-1.7.8
$ make clean
$ ./configure --add-module=/home/takeswim/ngx_mruby --add-module=/home/takeswim/ngx_mruby/dependence/ngx_devel_kit --prefix=/usr/local/nginx/
$ make
```

これでngx_mrubyが組み込まれたnginxが出来ました。
`$ sudo make install`でインストールします。

念のためnginx.confに設定を入れてngx_mrubyが動くのか試します。
serverディレクティブに以下のようにlocation /helloの設定を追加。

```lang:nginx.conf
:
:
        location / {
            root   html;
            index  index.html index.htm;
        }

    location /hello {
        mruby_content_handler_code '
            Server = Nginx
            Server.echo "WORLD"
        ';
    }
:
:
```

手動起動して、ブラウザで
http://localhost/hello
へアクセス。WORLDが返ってきました。良かった！



## ngx_mruby側のmakeでngx_mrubyつきnginxを作る
先ほどはnginx側でmakeをしていましたが、ngx_mruby側だけで完結することもできます。
既存のnginxがない状態からの場合、この手法は便利です。

git cloneでngx_mrubyを取得後submodule updateまでは同じ手順です。
configure時、`--with-ngx-config-opt`でnginx側のconfigureオプションを設定、makeします。

```
$ ./configure --with-ngx-src-root=/home/takeswim/nginx-1.7.8 --with-ngx-config-opt="--prefix=/usr/local/nginx/"
$ make
```

これでngx_mrubyのmake内でnginxのmakeも実行され、ngx_mruby組み込み済みのnginxが完成します。
`$ sudo make install`でnginxをインストールします。


# ngx_mruby側のbuild.shでngx_mrubyつきnginxを作る
去年の12月にあったようで丸一年見過ごしてました…
前述のmrubyに関するsubmodule updateどころか、nginxのソースが無かったらダウンロードもしてくれます。
先程nginxが無いときは便利…と書いていましたが、こちらの方がもっと簡単でした。

git cloneでngx_mrubyを取得後、
```
$ NGINX_CONFIG_OPT_ENV='--prefix=/usr/local/nginx' NGINX_SRC_ENV='/home/takeswim/nginx-1.7.8' sh build.sh
```

環境変数NGINX_CONFIG_OPT_ENVでnginx側に渡すオプション、NGINX_SRC_ENVでnginxのソースpathを設定します。
これでngx_mruby組み込み済みのnginxが完成します。
`$ sudo make install`でnginxをインストールします。

# まとめ
nginxにngx_mrubyを組み込む大枠の流れは…

* ngx_mrubyをgit cloneで取得後submodule取得し環境を整えつつmake
* nginxで`configure --add_module=[ngx_mrubyパス]`のちmake

これについて3つの手法を説明しました。

1. 上記通りの手順を取る
2. ngx_mruby側のmakeのみで作成する
3. build.shを使い作成する

個人的にはnginxインストールついでのngx_mruby組み込みという状況が多く、2をよく使っていたのですが、同じ理由であれば3でも問題ないと思いますし、既存のnginxを使い続ける必要があるのであれば1も選択としてあると思います。状況に応じて柔軟に！

# (番外編)前作ったnginxのconfigオプションなんて覚えてないよ！
既存のnginxのmakeし直しとなると、旧nginxのconfigオプションも引き継がないと…だけど普通覚えてないですよね。
そんな貴方にnginx -Vオプション(Vは大文字)があります。

```
$ /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.7.8
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) 
configure arguments: --add-module=/home/takeswim/ngx_mruby/ --add-module=/home/takeswim/ngx_mruby/dependence/ngx_devel_kit
```

configure argumentが指定したnginxをmakeした時のconfigureオプションになります。
この辺りをコピペして利用するとよいかと思います！

* * *

明日はainoyaさんの「mod_mrubyを使ってJWTベースの認証プロキシを作る」です！