どうも、シローです。
仕事でNginxの設定を見ることが多いのですが、ググりながら挙動を確認することが多いので、
Nginxのなんたるかの基礎を勉強している最中です。
それで今回はNginxでよく使われるワード「ディレクティブ」についてまとめました。
ディレクティブってなんぞや
ディレクトティブってワードなんですけど。どうやらディレクション(ディレクターがやってること)から派生しているっぽいです。
ディレクションって聞くと、エンジニアの人なら、「あー、なんか偉そうに命令してくること」って思うかもです。笑
そうです、ディレクティブっていうのは簡単にいうと「命令」です。
Nginxにおいてのディレクティブは、「ソースファイルはここのを使って!」や「ログファイルはここに書き込んで!」といった命令を行います。
Nginxには2種類のディレクティブがある
さて、ディレクティブの意味についてなんとなくわかったところで、次はディレクティブの種類について触れようとおもいます。
Nginxのディレクティブには大きくわけて2種類あります。
プログラムコード的な表現すると、
- 変数型のディレクティブ
- スコープで範囲指定するタイプのディレクティブ
です。
変数型とは
変数型のディレクティブでは実行するroot(ソースファイルのルートディレクトリ)やaccess_log(アクセスしたときのログを書き込むファイル)といった
Nginxで決められた変数に値を入れることで、Nginxの振る舞いを決めることができます。
よくある例として
ソースファイルのルートディレクトリを指定
1 |
root /var/www/html; |
クセスしたときのログを書き込むファイルを指定
1 |
access_log /var/log/nginx/access_log; |
があります。
要するにシステムの振る舞いに関する直接的な命令を記述しているので、Nginxの挙動を変えたいなーってときはだいたいこのディレクティブをいじるだろうとおもいます。
スコープ型とは
スコープ型のディレクティブでは先程の変数型ディレクティブの有効範囲を決めることができます。
また、その有効範囲のことをコンテキストといいます。
スコープ型のディレクティブにはhttpサーバ範囲を示す http {} や ドメイン範囲を示す server {} などがあります。
変数型のディレクティブと組み合わせた例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; server { listen 80; server_name localhost; location / { try_files $uri $uri/ =404; } } } |
スコープ型のディレクティブの中に変数型のディレクティブが記述されています。
Nginxアレルギーにとってはもうこんがらがっているかと思います。
「どのスコープにディレクティブを書けばいいの?」って。
これについてはディレクティブとコンテキストの関係性について知らなければなりません。
ディレクティブとコンテキストの関係性
先程少し触れましたが、コンテキストとはスコープ型ディレクトリの範囲のことで、
原則としてディレクティブはコンテキストの中に記述しなければいけません。
そうなので、コンテキストの中に記述するわけですが、次の2つの決まりを覚えておくと良いです。
ディレクティブには記述できるコンテキストが決まっている
これは主にスコープ型のディレクティブに関する規則なのですが、ディレクティブにはどのコンテキスト内に書かなかれば行けないかが定義されています。
例えば、serverディレクティブはhttpコンテキストの中に書かなければ行けません。
それぞれのディレクティブがどのコンテキスト内に記述しなければいけないのかを理解しましょう。
ちなみに一番外側のディレクティブであるhttp、eventsが記載されているコンテキストはmainコンテキストと呼ばれます。
よく使われるディレクティブと記述できるコンテキストは↓の通り
httpディレクティブ
構文 | http {...} |
コンテキスト | main |
意味 | httpサーバの全体を包むコンテキストを定義 |
serverディレクティブ
構文 | server {...} |
コンテキスト | http |
意味 | ポート番号やホスト名を定義できるコンテキストを定義(バーチャルサーバともいう) |
locationディレクティブ
構文 | location [ = | ~ | ~* | ^~ ] URI {...} |
コンテキスト | server, location |
意味 | マッチするURIごとのコンテキストを定義 |
listenディレクティブ
構文 | listen アドレス[ポート番号] [default_server];
listen [ポート番号] [default_server]; |
コンテキスト | server |
意味 | バーチャルサーバ内で使用するアドレス、ポート番号を指定する |
server_nameディレクティブ
構文 | server_name ホスト名; |
コンテキスト | server |
意味 | バーチャルサーバで使用するホスト名を指定する |
rootディレクティブ
構文 | root ディレクトリパス; |
コンテキスト | http, server, location |
意味 | 公開するディレクトリを指定する |
access_logディレクティブ
構文 | access_log ファイルパス; |
コンテキスト | http, server, location |
意味 | ログファイルの出力先を指定する |
error_logディレクティブ
構文 | error_log ファイルパス; |
コンテキスト | http, server, location |
意味 | エラーログファイルの出力先を指定する |
子階層のコンテキストほど、優先して適用される
プログラムの変数もそうなのですが、同じ変数の場合スコープの中とスコープの外ではスコープの中の値が適用されます。
例えば、httpコンテキスト内のrootディレクティブよりもserverコンテキスト内のrootディレクティブの方が優先度が高いです。
1 2 3 4 5 6 7 8 |
http { root /var/www/html; # デフォルトではこっち server { listen 80; server_name sample-site.com; root /var/www/html/sample-site; # ドメインがsample-site.comならこっちを見る } } |
まとめ
以上がNginxのディレクティブの仕様についてです。
まとめると
- ディレクティブはNginxの振る舞いを定義する命令
- ディレクティブにはスコープ型と変数型の2種類がある
- スコープ型ディレクティブのスコープ内をコンテキストという
- ディレクティブにはそれを記述できるコンテキストが決められている
- 同じ変数型ディレクティブが記述された場合、子階層のコンテキストのディレクティブほど優先度が高くなる。
な感じです。
最後に僕がこの記事書くのに参考にした本を宣伝しといて終わります。
nginxを現場で活用するための知識を、実践的なノウハウを交えて解説した書籍です。
nginxのインストール方法や基本的な設定方法からはじめ、nginxを利用した「静的コンテンツ配信サーバ」「HTTPSサーバ」「Webアプリケーションサーバ」「大規模コンテンツ配信システム」の構築方法をそれぞれ詳しく紹介しています。後半ではnginxサーバのモニタリングやログの収集、そして軽量スクリプト言語Luaでnginxを拡張する方法について解説しているので、nginxをこれから使う方はもちろん、さらに活用したい方にもお勧めです。