NGINX UnitをDockerで動かす


# はじめに
Nginxからリリースされた新しいサーバ、NGINX Unit（正式名称はUnitで、他のプロダクトと区別するためにNGINX Unitと呼んでいます）について、Dockerで動かしました。

https://github.com/yousan/nginx-unit


> 現時点でPHP、Go、Pythonに対応。Java、Ruby、Node.jsにも対応予定です。
> NGINX Unitの最大の特徴として挙げられているのは、最初から動的制御が可能なように設計されており、アプリケーションの入れ替えやバージョンアップなどを再起動することなくシームレスに行えるところです。
http://www.publickey1.jp/blog/17/nginx_unit.html


ということで、ソケットファイルを使ったHTTP通信でサーバのコンフィギュレーションが可能、というのが最大の特徴のようです。

Linuxの場合にはソケットファイルを共有してホスト側のcURLを利用することができます。

# 動かし方
## NGINX Unitの起動
GitHubのリポジトリにdocker-composeを置いています。こちらから動かすと簡単です。

```bash
$ git clone https://github.com/yousan/nginx-unit
$ cd nginx-unit
$ docker-compose up
```

<img width="422" alt="Screen Shot 2017-09-13 at 17.37.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/2fcd4251-974c-039a-07a3-f361f4ada32e.png">

dockerコマンド手動だとこんな感じで動きます。

```bash
$ docker run --name some-nginx-unit -v /var/www:/www/root -v /var/run:/var/run:rw  -p 8200:8200 -p 8300:8300  yousan/nginx-unit
```

ドキュメントルートにするディレクトリ、ソケットファイル、HTTP待受ポートの指定が必要です。

## NGINX Unitに開始コマンドを送る

### コンテナ内部で制御
コンテナ内部で作業をします。コンテナでbashを開きます。

```bash
$ docker exec -it nginx-unit /bin/bash
```

<img width="470" alt="Screen Shot 2017-09-14 at 11.44.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/17e96fdf-62af-35bc-bedb-3d323cc7ebef.png">

NGIN Unitでは制御するためにJSONファイルでやり取りを行います。
その為ホスト側のjsonディレクトリをマウントしておくと、コンテナ内でのcurlで利用できるので便利です。
上述のdocker-composeで起動した場合には、`/root/json`に入っています。

```bash
$ curl -X PUT -d @/root/json/start.json --unix-socket /var/run/control.unit.sock  http://localhost/
```

中身はこんな感じです。

```json:start.json
{
  "listeners": {
    "*:8300": {
      "application": "blogs"
    }
  },
  "applications": {
    "blogs": {
      "type": "php",
      "workers": 20,
      "root": "/www/root",
      "index": "index.php"
    }
  }
}
```

<img width="827" alt="Screen Shot 2017-09-14 at 11.46.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/6ba66041-fd3b-29d9-6220-ea374a768a09.png">


## ホスト側から制御する
Linuxの場合にはsocketファイルを共有することで、ホスト側から制御を行うことができます。

```bash
$ sudo curl -X PUT -d @./json/start.json --unix-socket ./run/control.unit.sock http://localhost/
```

コマンドを送ると結果が帰ってきます。

<img width="752" alt="Screen Shot 2017-09-13 at 17.44.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/f21f8453-9ad9-aa01-8b2b-500d95362ebd.png">

ホスト側から制御する利点は、JSONファイルなどをホスト側のエディタで編集できることです。
またcurlのコマンドもホスト側のものを使えるので、細かい所でオプションが違って動かない、ということを防ぐことができます。（とは言えcurlはかなり互換性が高そうです）

## 接続試験
8300で待受をさせたので繋いでみます。

```bash
$ curl -s http://localhost:8300 | less
```

ブラウザでも http://localhost:8300 に繋いでみます.

<img width="553" alt="Screen Shot 2017-09-14 at 11.52.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/499cf47e-5923-7c2e-0106-b299e216f1fa.png">


phpinfo() が表示されました！バッチリですね！

<img width="759" alt="Screen Shot 2017-09-13 at 17.45.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/ffcf9c47-b39a-4cef-bb1a-33a2bab402fc.png">


# ToDO
1. socketファイルがroot権限になっているのでsudo curlしないとダメなので直したいです。
2. ~~Macでsocketファイルが共有できない…。betaなら行ける?  https://github.com/docker/for-mac/issues/1962~~
コンテナ内部で作業すればOK
3. アプリケーションを動かしてみたいです

# 参考サイト
すごく参考になりました。恐らく公式ドキュメントから情報を拾ったのだと思います、それが結構大変なので助かりました。
http://yaaamaaaguuu.hatenablog.com/entry/2017/09/08/031316

公式マニュアル
http://unit.nginx.org/docs-nginx-unit.html