インフラチームの@cubicdaiyaです。今回はnginxのビルドプロセスを自動化するツールであるnginx-buildについて紹介します。
メルカリとnginx
メルカリでは多数のnginxを活用し、高速なレスポンスやサービスの安定稼働を実現するのに重要な役割を果たしています。実際の活用事例には、
- リバースプロキシ、L7ロードバランサ
- TLSターミネーション、SPDYゲートウェイ
- 静的コンテンツの配信、キャッシュ
- ngx_dynamic_upstreamを用いたゼロダウンタイムデプロイメント
- ngx_lua(OpenResty)を用いたサービスコンポーネントの開発
などが挙げられます。そしてメルカリではこれら多数の用途のnginxをnginx-buildでソースコードからビルドしています。(OpenResty以外は合わせてrpm化も行っています)
既存のビルド済みパッケージの利用とソースコードからのビルド
nginxはyumやaptといった各Linuxディストリビューションのパッケージ管理ツールでビルド済みのパッケージをインストールすることができますし、公式サイトでもビルド済みパッケージを配布しています。インストールも簡単なので特にこだわりや理由がなければ広く配布されているビルド済みパッケージを利用するだけで問題ないでしょう。
一方で既存のビルド済みパッケージを利用する場合以下のデメリットが挙げられます。
- ビルド時の
configure
オプションが選べない(既に決まっている) - サードパーティのモジュールが組み込めない
「1. ビルド時のconfigure
オプションが選べない」が問題になることは少ないかもしれませんが、「2. サードパーティのモジュールが組み込めない」は大きなマイナスポイントです。というのもnginxのモジュールはすべてビルド時に組み込む必要があるためです。(この状況は今後変わるかもしれません。詳しくはこちら)
nginxをソースコードからビルドする
次にnginxをソースコードからビルドする手順を書いてみます。
wget http://nginx.org/download/nginx-1.9.4.tar.gz tar zxf nginx-1.9.4.tar.gz cd nginx-1.9.4 ./configure make make install
非常に簡単です。しかしnginxを本格的にプロダクションで利用する場合は考えなければならないことが数多くあります。パッと思いつくものを挙げてみます。
- 大量にあるビルドオプションの指定
- PCRE、zlib、OpenSSLなどの依存ライブラリの組み込み・バージョン管理
- サードパーティモジュールの組み込み・バージョン管理
- 上記手順の自動化・構成管理・メンテナンス
これらの手間を大幅に省くために開発したのが次に紹介するnginx-buildです。
nginx-build〜seamless nginx builder〜
nginx-buildはnginxのビルドプロセスを自動化するためのツールです。Goで書かれています。
こちらからビルド済みの実行バイナリをダウンロードすることができます。MacユーザならHomebrewでインストールすることも可能です。
brew tap cubicdaiya/nginx-build brew install nginx-build
また、Goがインストールされていればgo get
でインストールすることができます。
go get -u github.com/cubicdaiya/nginx-build
nginx-buildでnginxをビルドする
それではnginx-build
でnginxをビルドしてみましょう。
$ nginx-build -d work -v 1.9.4 nginx-build: 0.4.4 Compiler: gc go1.5 2015/08/23 21:37:57 Download nginx-1.9.4..... 2015/08/23 21:38:03 Extract nginx-1.9.4.tar.gz..... 2015/08/23 21:38:03 Generate configure script for nginx-1.9.4..... 2015/08/23 21:38:03 Configure nginx-1.9.4..... 2015/08/23 21:38:08 Build nginx-1.9.4..... 2015/08/23 21:38:12 Complete building nginx! nginx version: nginx/1.9.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) configure arguments: 2015/08/23 21:38:12 Enter the following command for install nginx. $ cd work/1.9.4/nginx-1.9.4 $ sudo make install $
nginx-build
が行うのはソースコードやライブラリのダウンロードとコンパイルまでなので後は出力にしたがってインストール(make install
)します。
configureオプションを指定する
nginx-build
にはnginxのconfigure
のオプションを直接付加することができます。
$ nginx-build \ > -d work \ > -v 1.9.4 \ > --with-http_gzip_static_module \ > --with-http_gunzip_module \ > --with-http_stub_status_module \ > --with-http_realip_module nginx-build: 0.4.4 Compiler: gc go1.5 2015/08/23 21:36:11 nginx-1.9.4 already exists. 2015/08/23 21:36:11 Generate configure script for nginx-1.9.4..... 2015/08/23 21:36:11 Configure nginx-1.9.4..... 2015/08/23 21:36:15 Build nginx-1.9.4..... 2015/08/23 21:36:20 Complete building nginx! nginx version: nginx/1.9.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) configure arguments: --with-http_gunzip_module --with-http_stub_status_module --with-http_realip_module --with-http_gzip_static_module 2015/08/23 21:36:20 Enter the following command for install nginx. $ cd work/1.9.4/nginx-1.9.4 $ sudo make install $
なおオプションを直接与える方法にはほんの少しだけ制限があるのでconfigure
の実行スクリプトをファイルで指定する方法も用意しています。
#!/bin/sh ./configure \ --with-http_gzip_static_module \ --with-http_gunzip_module \ --with-http_stub_status_module \ --with-http_realip_module
このシェルスクリプトファイルをnginx-build
に-c
オプションで付加することでnginxのconfigure
オプションを指定できます。
$ nginx-build -d work -v 1.9.4 -c configure.sh nginx-build: 0.4.4 Compiler: gc go1.5 2015/08/23 21:37:02 Download nginx-1.9.4..... 2015/08/23 21:37:07 Extract nginx-1.9.4.tar.gz..... 2015/08/23 21:37:07 Generate configure script for nginx-1.9.4..... 2015/08/23 21:37:07 Configure nginx-1.9.4..... 2015/08/23 21:37:11 Build nginx-1.9.4..... 2015/08/23 21:37:16 Complete building nginx! nginx version: nginx/1.9.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) configure arguments: --with-http_gzip_static_module --with-http_gunzip_module --with-http_stub_status_module --with-http_realip_module 2015/08/23 21:37:16 Enter the following command for install nginx. $ cd work/1.9.4/nginx-1.9.4 $ sudo make install $
依存ライブラリの組み込み
nginxにはいくつか依存ライブラリがあります。代表的なのは以下の3つです。
nginxはこれらのライブラリを静的あるいは動的に組み込めるようになっています。動的組み込みの場合nginxのconfigureスクリプトがシステムのパスを検索してライブラリのパスを発見してくれますが、静的組み込みに場合は別途依存ライブラリのパスを指定する必要があります。
./configure \ -with-pcre=../pcre-8.37 \ --with-zlib=../zlib-1.2.8 \ --with-openssl=../openssl-1.0.2d
nginx-build
はこれらのライブラリの組み込みをダウンロードも含めて自動化するためのオプションを用意しています。
$ nginx-build \ -d work \ -v 1.9.4 \ -pcre \ -pcreversion=8.37 \ -zlib \ -zlibversion=1.2.8 \ -openssl \ -opensslversion=1.0.2d nginx-build: 0.4.4 Compiler: gc go1.5 2015/08/23 21:47:30 Download nginx-1.9.4..... 2015/08/23 21:47:30 Download zlib-1.2.8..... 2015/08/23 21:47:30 Download openssl-1.0.2d..... 2015/08/23 21:47:30 Download pcre-8.37..... 2015/08/23 21:47:32 Extract zlib-1.2.8.tar.gz..... 2015/08/23 21:47:33 Extract pcre-8.37.tar.gz..... 2015/08/23 21:47:34 Extract openssl-1.0.2d.tar.gz..... 2015/08/23 21:47:37 Extract nginx-1.9.4.tar.gz..... 2015/08/23 21:47:37 Generate configure script for nginx-1.9.4..... 2015/08/23 21:47:37 Configure nginx-1.9.4..... 2015/08/23 21:47:41 Build nginx-1.9.4..... 2015/08/23 21:50:47 Complete building nginx! nginx version: nginx/1.9.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) built with OpenSSL 1.0.2d 9 Jul 2015 TLS SNI support enabled configure arguments: --with-pcre=../pcre-8.37 --with-openssl=../openssl-1.0.2d --with-zlib=../zlib-1.2.8 --with-http_ssl_module 2015/08/23 21:50:47 Enter the following command for install nginx. $ cd work/1.9.4/nginx-1.9.4 $ sudo make install $
--with-http_ssl_module
はOpenSSL関連のオプションを指定すると自動的に付加されます。(でないとコンパイルに失敗してしまうので)
サードパーティモジュールの組み込み
nginxにサードパーティのモジュールを組み込むには--add-module
オプションを利用します。
./configure --add-module={モジュールのパス}
先述の通りnginx-build
ではnginxのconfigure
のオプションを直接指定出来るので--add-module
も利用可能です。ここではecho-nginx-moduleとheaders-more-nginx-moduleを組み込んでみます。
$ git clone https://github.com/openresty/echo-nginx-module.git $ git clone https://github.com/openresty/headers-more-nginx-module.git $ nginx-build \ -d work \ -v 1.9.4 \ --add-module=echo-nginx-module \ --add-module=headers-more-nginx-module nginx-build: 0.4.4 Compiler: gc go1.5 2015/08/23 22:05:26 Download nginx-1.9.4..... 2015/08/23 22:05:32 Extract nginx-1.9.4.tar.gz..... 2015/08/23 22:05:32 Generate configure script for nginx-1.9.4..... 2015/08/23 22:05:32 Configure nginx-1.9.4..... 2015/08/23 22:05:37 Build nginx-1.9.4..... 2015/08/23 22:05:42 Complete building nginx! nginx version: nginx/1.9.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) configure arguments: --add-module=/home/bokko/nginx/echo-nginx-module --add-module=/home/bokko/nginx/headers-more-nginx-module 2015/08/23 22:05:42 Enter the following command for install nginx. $ cd work/1.9.4/nginx-1.9.4 $ sudo make install $
さきほどの依存ライブラリ組み込みの例ではダウンロードも自動化していましたが、サードパーティモジュールについてもダウンロードの自動化は可能です。次のようなiniファイル(modules3rd.ini)を用意します。
[echo-nginx-module] form=git url=https://github.com/openresty/echo-nginx-module.git rev=v0.58 [headers-more-nginx-module] form=git url=https://github.com/openresty/headers-more-nginx-module.git rev=v0.261
このファイルをnginx-build
に-m
オプションで付加します。
$ nginx-build -d work -v 1.9.4 -m modules3rd.ini nginx-build: 0.4.4 Compiler: gc go1.5 2015/08/23 22:25:22 Download headers-more-nginx-module-v0.261..... 2015/08/23 22:25:22 Download nginx-1.9.4..... 2015/08/23 22:25:22 Download echo-nginx-module-v0.58..... 2015/08/23 22:25:28 Extract nginx-1.9.4.tar.gz..... 2015/08/23 22:25:28 Generate configure script for nginx-1.9.4..... 2015/08/23 22:25:28 Configure nginx-1.9.4..... 2015/08/23 22:25:32 Build nginx-1.9.4..... 2015/08/23 22:25:37 Complete building nginx! nginx version: nginx/1.9.4 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) configure arguments: --add-module=../echo-nginx-module --add-module=../headers-more-nginx-module 2015/08/23 22:25:37 Enter the following command for install nginx. $ cd work/1.9.4/nginx-1.9.4 $ sudo make install $
nginxをビルドした後にビルド時のconfigure
のオプションを確認するのはnginx -V
を実行します。しかし、サードパーティモジュールの場合、どのバージョンのサードパーティモジュールを組み込んだかについては確認するのが困難です。
なのでnginx-build
の-m
オプションを利用してサードパーティモジュールの組み込み手順をファイルに残しておくことは後々のnginxの構成管理をやりやすくするためにもなります。
nginxの派生プロジェクトへの対応
nginxには以下の派生プロジェクトが存在します。
nginx-build
は本家のnginxだけでなくこれらの派生プロジェクトのソースコードのビルドにも対応しています。
OpenResty
OpenRestyはnginxにngx_luaをはじめとする便利なサードパーティモジュールやLuaとLuaJIT、ngx_lua向けのモジュール群(restyモジュール)をバンドルしたアプリケーションフレームワークです。メルカリでも一部のサービスコンポーネントで利用しています。nginx-build
でOpenRestyをビルドするには-openresty
オプションを付加します。また、-openrestyversion
でバージョンを指定することが可能です。
nginx-build -d work -pcre -openresty -openrestyversion=1.9.3.1
Tengine
Tengineはnginxのフォークプロジェクトです。モジュールの動的組み込みやアップストリームのヘルスチェックなど本家のnginxには含まれていない(あるいは有償版のNGINX Plusにしかない)便利な機能が利用できるのが特徴です。nginx-build
でTengineをビルドするには-tengine
オプションを付加します。また、-tengineversion
でバージョンを指定することが可能です。
nginx-build -d work -tengine -tengineversion=2.1.1
まとめ
nginxのビルドプロセスを自動化するためのツールであるnginx-buildについて紹介しました。nginx-build
を利用することで以下の作業の大部分を自動化することができます。
- nginxのビルド
- 依存ライブラリのダウンロードと組み込み
- サードパーティモジュールのダウンロードと組み込み
また、ビルドする際のconfigure
のオプションやサードパーティモジュールの組み込み方法をファイルに残すことで後々のnginxの構成管理に役立てることができます。
それでは快適なnginxライフを。