nginx.orgのrpmをカスタマイズしてfedora coprでビルド・配布するのを試してみた

nginx Advent Calendar 2015の12/4(金)の枠が空いたまま過ぎていたので、今からこの記事を書いて登録しようと思います。

## はじめに

nginxはCentOS 7だとepelに含まれていますが、こちらはバージョンが古いです。最近までは[nginx: download](http://nginx.org/en/download.html)のyumレポジトリを活用していました。が、luaを使いたい場合など、追加モジュールを利用する場合はソースからビルド必要があります。

[nginx-buildでnginxをビルドしよう - Qiita](http://qiita.com/cubicdaiya/items/a0411c190f043a85ad2f)で説明されている方法もありますが、CentOSならrpmで管理したいという思いもあります。

そこで、[fedora projectのcoprというサービス](https://copr.fedoraproject.org/coprs/)でngnxのrpmをビルド・配布するのを試してみました。

## 私が作成したnginxのrpmについて
Travis CIでdockerでnginxのsrpmを作ってcoprでビルドするのに必要なファイルをgithubの[hnakamur/nginx-rpm](https://github.com/hnakamur/nginx-rpm)に置いています。

nginx.orgのrpmのspecファイルをベースに以下の3つのモジュールをビルドするようにしています。

* [openresty/lua-nginx-module](https://github.com/openresty/lua-nginx-module)
* [yaoweibin/nginx_upstream_check_module](https://github.com/yaoweibin/nginx_upstream_check_module)
* [replay/ngx_http_consistent_hash](https://github.com/replay/ngx_http_consistent_hash)

## srpmの作成

srpmのビルド手順は[Dockerfile](https://github.com/hnakamur/nginx-rpm/blob/be3a68cad3cdb060eee771a8a683fc943646609b/Dockerfile)に書いています。主な部分を以下に抜粋します。

```
…(略)…
 && cd /root/rpmbuild/SRPMS \
 && curl -sLO http://nginx.org/packages/mainline/centos/7/SRPMS/nginx-${NGINX_VERSION}-1.el7.ngx.src.rpm \
 && rpm -i nginx-${NGINX_VERSION}-1.el7.ngx.src.rpm \
 && cd /root/rpmbuild/SOURCES \
 && curl -sLO https://github.com/openresty/lua-nginx-module/archive/v${NGX_LUA_VERSION}.tar.gz#/lua-nginx-module-${NGX_LUA_VERSION}.tar.gz \
 && curl -sLO https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.tar.gz#/nginx_upstream_check_module-master.tar.gz \
 && curl -sLO https://github.com/replay/ngx_http_consistent_hash/archive/master.tar.gz#/ngx_http_consistent_hash-master.tar.gz

ADD nginx.spec.patch /root/rpmbuild/SPECS/

RUN cd /root/rpmbuild/SPECS \
 && patch -p0 < nginx.spec.patch \
 && rpmbuild -bs nginx.spec
…(略)…
```

nginx.orgで提供しているrpmに含まれる `nginx.spec` に以下のパッチを当てています。

```https://github.com/hnakamur/nginx-rpm/blob/169bf4f4e49d8a4b80626481de42a67f3ac8034a/nginx.spec.patch
--- nginx.spec.orig	2015-11-18 00:07:19.000000000 +0900
+++ nginx.spec	2015-12-06 17:51:40.000000000 +0900
@@ -74,11 +74,16 @@
 Source9: nginx.upgrade.sh
 Source10: nginx.suse.logrotate
 
+Source100: https://github.com/openresty/lua-nginx-module/archive/v0.9.19.tar.gz#/lua-nginx-module-0.9.19.tar.gz 
+Source101: https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.tar.gz#/nginx_upstream_check_module-master.tar.gz
+Source102: https://github.com/replay/ngx_http_consistent_hash/archive/master.tar.gz#/ngx_http_consistent_hash-master.tar.gz
+
 License: 2-clause BSD-like license
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 BuildRequires: zlib-devel
 BuildRequires: pcre-devel
+BuildRequires: luajit-devel
 
 Provides: webserver
 
@@ -98,7 +103,8 @@
 %endif
 
 %prep
-%setup -q
+%setup -q -a 100 -a 101 -a 102
+patch -p0 < ./nginx_upstream_check_module-master/check_1.9.2+.patch
 
 %build
 ./configure \
@@ -136,6 +142,9 @@
         --with-mail_ssl_module \
         --with-file-aio \
         --with-ipv6 \
+        --add-module=./lua-nginx-module-0.9.19 \
+        --add-module=./nginx_upstream_check_module-master \
+        --add-module=./ngx_http_consistent_hash-master \
         --with-debug \
         %{?with_http2:--with-http_v2_module} \
         --with-cc-opt="%{optflags} $(pcre-config --cflags)" \
@@ -178,6 +187,9 @@
         --with-mail_ssl_module \
         --with-file-aio \
         --with-ipv6 \
+        --add-module=./lua-nginx-module-0.9.19 \
+        --add-module=./nginx_upstream_check_module-master \
+        --add-module=./ngx_http_consistent_hash-master \
         %{?with_http2:--with-http_v2_module} \
         --with-cc-opt="%{optflags} $(pcre-config --cflags)" \
         $*
```

変更内容を説明します。

* luajitを使いたいので `BuildRequires: luajit-devel` を追加
* 使用したいモジュールのソースのURLを `Source100`, `Source101`, `Source102` に指定
    * 元の `nginx.spec` に `Source0` から `Source10` まで書かれているのでnginxの将来のバージョンで `Source` が増えても衝突しないように100からとしました。
    *  `https://github.com/openresty/lua-nginx-module/archive/v0.9.19.tar.gz#/lua-nginx-module-0.9.19.tar.gz` のというURLの書き方については[rpmのspecファイルのSourceにGitHubの任意のコミットのtarballのURLを指定するときの良い書き方 · hnakamur's blog at github](https://hnakamur.github.io/blog/2015/12/06/good_rpm_spec_source_url_syntax_for_tarball_on_github/)をご参照ください。
* %setupに `Source100`, `Source101`, `Source102` を展開するためのオプションを追加
    * オプションについては[SPEC file sections explained](https://fedoraproject.org/wiki/How_to_create_an_RPM_package#SPEC_file_sections_explained)に説明があります。
* %setupの後に[yaoweibin/nginx_upstream_check_module](https://github.com/yaoweibin/nginx_upstream_check_module)に含まれるパッチ[check_1.9.2+.patch](https://github.com/yaoweibin/nginx_upstream_check_module/blob/10782eaff51872a8f44e65eed89bbe286004bcb1/check_1.9.2%2B.patch)を適用
* nginxのconfigureのオプションに使用したいモジュールごとに `--add-module=モジュールソースのディレクトリ` を追加

## coprでのrpmのビルド・配布

上記で作成したsrpmをcoprでビルドするのは [copr-build.sh](https://github.com/hnakamur/nginx-rpm/blob/be3a68cad3cdb060eee771a8a683fc943646609b/copr-build.sh)で行っています。詳細については[Travis CIとcopr.fedoraproject.orgを使ってrpmをビルド・配布するのを試してみた · hnakamur's blog at github](https://hnakamur.github.io/blog/2015/11/26/use_travis_and_copr_to_build_and_host_rpm/)をご参照ください。

## ビルドされたrpmのインストール方法

[hnakamur/nginx Copr](https://copr.fedoraproject.org/coprs/hnakamur/nginx/)の"Installation Instructions"にも書いていますが、作成したrpmは以下のコマンドでインストールできます。

```shell-session
sudo curl -sL -o /etc/yum.repos.d/hnakamur-nginx.repo https://copr.fedoraproject.org/coprs/hnakamur/nginx/repo/epel-7/hnakamur-nginx-epel-7.repo

sudo yum install nginx
```

## おわりに
coprを利用すると自作のrpmをホスティングしてくれるのでかなり便利です。みなさんもいろいろなrpmをcoprでビルド・配布してみてはいかがでしょうか。