nginxについてまとめ(設定編)

## 概要

前回: [nginxについてまとめ(導入編)](http://qiita.com/morrr/items/929e9cb35914a7f3a652)

今回はApacheでよく使う機能を中心に、目的別に設定方法を調査した。


## 設定ファイルのルール
- モジュール = nginxの構成単位
    - 設定ファイルはモジュール単位で記述する

    ```nginx
    http{
        # httpモジュールの設定
    }

    # coreモジュールの設定はくくる必要がない
    ```

    モジュール名 | 内容
    --- | ---
    core | プロセス制御、設定ファイル制御、ロギング
    event | イベント処理(パフォーマンス・チューニング
    http | webサーバ関連の設定
    mail | メール関連の設定


- ディレクティブ = 命令
    - ディレクティブは他のディレクティブを内包し得る

    ```nginx
    http{
        server{
            # ...
        }
    }
    ```

- コンテキスト = モジュールあるいはディレクティブが作るスコープ
    - `{ }` で囲まれた範囲を指す
    - coreモジュールのコンテキスト(一番外側)はmainコンテキストと呼ばれる


## 目的別の設定例
### 一般設定
#### 実行ユーザを指定する
```nginx
# nginxユーザを設定
user nginx;
```

#### 設定ファイルを読み込む
ルート設定ファイル`nginx.conf`内に`include`を記述することで、他の設定ファイルの読み込みが可能。設定ファイルはApacheと同様に`conf.d/`に格納することが多い様子。

```nginx
include /usr/local/etc/nginx/conf.d/ssl.conf
```

#### パフォーマンスを調整する
- `worker_process`により実行プロセス数を指定できる

```nginx
# 2プロセスで動かす
# CPUのコア数より多く設定してもパフォーマンスは上がらないとのこと
worker_processes 2;
```

- `worker_connections`によりコネクション数を制限する

```nginx
events{
    worker_connections  512;
}
```

- その他、`keepalive_requests`、`keepalive_timeout`、`tcp_nopush`, `tcp_nodelay`などなど...



#### エラーログを指定する
- httpなど、core以外のコンテキストに対して個別に設定が可能
- ログレベルを設定可能
    - デフォルトはコンテキストに依存する
    - レベルは低い順に、`debug, info, notice, warn, error, crit, alert, emerg`

- エラーログに対してフォーマットを指定する方法は不明だった。レベル指定以外できない？


```nginx:nginx.conf
error_log  logs/nginx/error.log debug;
```



### Webサーバ設定
#### 基本設定
- `listen` によりIPとポートを指定する
- `server_name`によりサーバ名を指定する
- `root`によりドキュメントルートを指定する
- `charset`によりレスポンスヘッダのContent-typeを指定する

```nginx
http{
    # listenはポートのみ指定でも可
    listen 80;
    server_name www.example.com;
    root /var/www/html/www.example.com;
    charset UTF-8;
}
```

#### アクセスログを設定する

- `log_format`で、フォーマットに名前をつけて保持する
    - [フォーマットの指定方法については公式を参照のこと。](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format)
    - 昔ながらの記号方式ではなく、`$time_local`のような定数形式で記述する

- `access_log`で、ログの種類と出力先を指定する

```nginx
http{
    log_format formatA '[$time_local]$connection - $status';
    access_log formatA /var/logs/nginx/access_log
}
```

#### 仮想サーバを構築する
##### ドメインベース
- `server`を復数記述することで、仮想サーバとして動作する
    - `http`内に記述できるディレクティブは、だいたい`server`内にも記述できる様子

```nginx
http{
    server{
        server_name alpha.example.com;
    }
    server{
        server_name bravo.example.com;
    }
}
```

##### IPベース
- `listen`で別個のIPを指定することで、IPベースの仮想サーバを構築できる

```nginx
http{
    server{
        listen 192.168.0.1:80;
        server_name alpha.example.com;
    }
    server{
        listen 192.168.0.2:80;
        server_name bravo.example.com;
    }
}
```

#### エイリアスを指定する

- `location`により、パスごと個別のドキュメントルートを設定可能

```nginx
http{
    server{
        location /foo{
            root /path/to/foo;
        }
        location /bar{
            root /path/to/bar;
        }
    }
}
```

- なお、indexファイルは`index`で指定できた

```nginx
http{
   index index.html index.htm;
}
```

#### ファイル一覧を表示する/しない
- Apacheでいうところのindexesは、`autoindex`で指定できる

```nginx
http{
    # ファイル一覧を有効化
    autoindex on;
}
```

#### IPフィルタリング

- `allow` / `deny`でアクセスを許可 / 拒否する

```nginx
http{
    allow 127.0.0.1;
    deny all;
}
```

なお、__設定ファイルの上にあるルールが優先される__。

```nginx
# allowが優先されるため、全アクセスを許可する
http{
    allow all;
    deny all;
}

# denyが優先されるため、全アクセスを拒否する
http{
    deny all;
    allow all;
}
```
    
#### BASIC認証を設定する

- `auth_basic`でBASIC必須の旨とメッセージを、`auth_basic_user_file`で.htpasswdファイルを設定する

```nginx
http{
    auth_basic "BASIC AUTH";
    auth_basic_user_file /path/to/.htpasswd;
}
```

#### SSL(https)に対応する
- `listen`で443ポートを使うことを指定
- `ssl`でSSLを有効に
- `ssl_certificate`で証明書＋中間証明書のファイルを指定
- `ssl_certificate_key`で秘密鍵を指定

```nginx
http{
    # listen 443; ssl on; のように別々のディレクティブでも設定できる
    # 現行の版(>= v1.15.0)ではsslディレクティブは廃止されているので注意
    listen 443 ssl;

    ssl_certificate      /path/to/cert.pem;
    ssl_certificate_key  /path/to/cert.key;  
}
```

#### Rewriteルールを設定する
- `rewrite`でルールを指定する
    - `last`フラグを付けると、rewrite後にlocationディレクティブを再評価する
    - `break`フラグの場合は再評価しない

```nginx
# /a/b を /a-bに変換する
rewrite ^/(.*)/(.*)$ $1-$2 last;
```

## 不明点
#### .htaccessはないらしい
調べた限りでは、.htaccessのようにフォルダ別に動的な設定ファイルを配置する仕組みはなかった。

#### 制御構文
- `set`による変数定義, `if`による条件分岐など、スクリプト的な機能もある様子
- ただ[ドキュメントを見ると](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)、このディレクティブはrewrite関連の様子。それ以外の目的では使えない...?


## 参考
- [nginx - nginx documentation](http://nginx.org/en/docs/)
- [Qiita - Nginx設定のまとめ](http://qiita.com/syou007/items/3e2d410bbe65a364b603#server%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF)
- [Qiita - Apacheからnginxへ移行する際に気になったことメモ](http://qiita.com/nayuneko/items/a3b326e2e9466e4117d6)
- [インフラエンジニアWay - nginx連載3回目: nginxの設定、その1](https://heartbeats.jp/hbblog/2012/02/nginx03.html)
- [インフラエンジニアWay - nginx連載4回目: nginxの設定、その2 - バーチャルサーバの設定](https://heartbeats.jp/hbblog/2012/04/nginx04.html)
- [Siguniang's Blog - nginx rewriteのlastとbreakの違い](https://siguniang.wordpress.com/2014/02/16/nginx-url-rewriting-difference-between-break-and-last/)
- [遍歴プログラマ日記 - 実例で学ぶ、Nginxのrewriteに指定できるbreakとlastの違い](https://remotestance.com/blog/2903/)