nginxのバージョンについて

## はじめに
nginxのバージョンってあまり気にしたことがなかったけど、訳あってちょっと調べたのでまとめてみようと思う。とは言え特に難しいことはなく、よくある開発版・安定版の二つをメンテするというモデル。ただ、安定版のメンテ期間がやや特殊かなと思うのでその点は注意が必要そう。

## バージョンの考え方
[ここ](https://www.nginx.com/blog/nginx-1-12-1-13-released/)に図入りで説明されているので特に迷うことも無いと思うが、以下簡単にまとめておく。

* 基本は二つのバージョンをメンテし続ける
  * **安定版** (1.10, 1.12など偶数バージョン番号)
      * 新たな機能の追加はなく、基本は深刻なバグの修正とセキュリティ脆弱性の対応のみ
  * **開発版** (1.11, 1.13など奇数バージョン番号)
      * バグの修正に加えて、機能の追加を行いながら4〜6週間に一度ずつリリースを行う

* 安定版は1年に一度、4月にリリース。その直前の開発版から分岐して安定版とする。
* **新しい安定版が出たらその前の安定版はdeprecated(非推奨)となり、それ以降のアップデートは行われない**
* 開発版は安定版が切られたらその次からバージョンが上がる。例えば、1.11系の最後のバージョンは2017/4/4にリリースされた1.11.13だが、4/12に安定版の1.12.0がリリースされたので、その次の4/25の開発版は1.13.0になった。

やはり、「新しい安定版が出たら前の安定版のサポートは即止まる」というのは注意が必要そう。多少オーバーラップして前の安定版も暫くはサポートするというモデルを比較的よく見かけるが、nginxは潔く切ってしまうらしい。安定版を使って運用をしている人は注意しておくべきでしょう。LTS(Long-term Support)的なものが無いのかなと少し調べてみたけど有償のサービスも含めて無いっぽい。安定版のアップグレードは年に一度4月と決まっているので、アップグレードのタスクを期限を付けてバックログに入れておくというのが良いのかもしれない。

## 安定版・開発版どちらを使えば良い？
実は開発版は英語の正式名称が "Mainline"となっている。「主流版」とでも訳すべきかも知れないが、機能をどんどん追加していく一方で通常利用しても問題ない、単なる開発版ではないことを強調したいという意図が見える。
実際、[このドキュメント](https://www.nginx.com/blog/nginx-1-12-1-13-released/)でも「開発版をオススメする」と書かれている。そして「テストも開発版の方でガンガンかけているので、マジで安定版より安定している」というコメントも。一方で、「なるべくアップデートせず、今後1年間の間に入る機能拡張が直ぐに必要なければ安定版も良いよ」とのこと。

## 1.12/1.13バージョンアップ履歴
2017年11月現在の選択肢は1.12か1.13しかないわけだが、これまでどのようなアップデートが行われたかをまとめてみる(バグ修正は省略)。ソースは [ここ](http://nginx.org/en/CHANGES-1.12)と[ここ](http://nginx.org/en/CHANGES)なので詳細はそれらを見て下さい。

| 日付 | 1.12系 | 1.13系 |
| ---- | ----- | ------ |
| 2017/4/12| **1.12.0**<br>(1.11.13相当)| |
| 2017/4/25| | **1.13.0**<br>変更：バックエンド接続でSSL再ネゴシエーションが可能に<br>機能：`mail proxy`と`stream`モジュールの`listen`ディレクティブで`rcvbuf"と`sndbuf`パラメーターが利用可能に<br>機能：`return`と `error_page` ディレクティブで、308リダイレクトを返すことができるように<br>機能：`ssl_protocols` ディレクティブに `TLSv1.3` パラメーター追加<br>機能：シグナルをロギング時に送信元のプロセスのPIDを記録するように|
| 2017/5/30 | | **1.13.1**<br>機能：`set_real_ip_from`ディレクティブのパラメータとしてホスト名を使用可能に<br>機能：Vimのシンタックスハイライトが改善<br>機能：`worker_cpu_affinity`ディレクティブが DragonFly BSDで動くように<br>|
| 2017/6/27 | | **1.13.2**<br>変更：0から始まるレンジ指定で空ファイルの要求があったときに416の代りに200を返すようになった<br>機能：`add_trailer`ディレクティブが追加された |
| 2017/7/11 | **1.12.1**<br>セキュリティ脆弱性対応([CVE-2017-7529](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7529)) | **1.13.3**<br>セキュリティ脆弱性対応([CVE-2017-7529](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7529)) |
| 2017/8/8 | | **1.13.4**<br>`ngx_http_mirror`モジュールの追加 |
| 2017/9/5 | | **1.13.5**<br>`$ssl_client_escaped_cert`変数の追加|
| 2017/10/10 | | **1.13.6**<br>(バグ修正のみ)|
| 2017/10/17 | **1.12.2**<br>(バグ修正のみ) | |

##dockerで試してみる
オフィシャルリポジトリは[こちら](https://hub.docker.com/_/nginx/)。バリエーションとして、

* 安定版(1.12) か 開発版(1.13)か
* Perlが要るか要らないか
* OSがDebian LinuxかAlpine Linxuか

の2x2x2=8種類のバリエーションがある。この中でOSの違いをもう少し調べてみる。

ベースになっているのは2017/11/11現在、Debian版が最新安定版のスリム化バージョンの`debian:stretch-slim`、Alpine版が最新から一つ前の`alpine:3.5`。でそれぞれのイメージサイズを比べてみるとこうなる。

|Image|Size|
|----|----|
|debian:stretch-slim|55.3MB|
|alpine:3.5|3.99MB|

Debianのスリム化バージョンは、通常のコンテナ稼働時には必要ないマニュアルページやドキュメントを削除して55MBまでイメージサイズを削減している。ちなみにスリム化していない通常版は100MBあるので、ほぼ半分近い。が、Alpineは「うっそー」って思わず言いたくなるまさかの4MB未満である。ではこのAlpine Linuxとはなにか？

公式サイトが[ここ](https://alpinelinux.org/)にあるが、musl libcとbusyboxをベースにした軽量なLinuxディストリビューションとのこと。musl libcはlibcの一実装で、[ここ](http://www.etalabs.net/compare_libcs.html)に比較があるが、性能や機能をそれほど犠牲にすることなく軽量化を果たしているように見える。そしてbusyboxは昔からLinuxの組み込み用途で使われてきた「アーミーナイフ」的なツールで、一つのexecutableの中にLinuxで通常必要とされるコマンドをほぼ詰め込んでいる。これらを組み合わせ、不必要なものを徹底的に削ぎ落とした結果、ベースイメージが4MBという脅威のサイズになっている。

もちろん何かやるためにはそのための追加のコマンドやライブラリを追加しなければならず、その際にはapkというパッケージ管理ツールを使う。あれこれ追加すると結果的に他のOSと変わらないサイズになるという声もあるが、実際にnginx安定版を動かすのに必要なサイズを比べてみるとこうなる。

|Image|Size|
|----|----|
|nginx:stable|108MB|
|nginx:stable-alpine|15.5MB|

nginxを使ったコンテナの場合、通常はここに設定ファイルを追加するだけだからほぼほぼこれだけで動かせるはず。そうすると、100MB超と16MBで約1/6。もし機能的に・性能的に変わらないんだったらこの差は結構大きいんじゃないかなと思う。時間があったら同じ条件で性能評価とかしてみたいな...