nginxで最小のwebサーバーを立ち上げてみる

# はじめに

この記事を書いている人は普段はデータサイエンスっぽいことをしている人なのでweb系の知識は深くありません。
間違いのないように気をつけておりますが、どこか至らぬ点がございましたらご指南頂けますと幸いです。

# モチベーション
プログラミング言語を習い始めると多くの場合、最初に`Hello world`されると思います。
流石にこのレベルだと簡単すぎな気もしなくはないですが、最も低レベルのことから順に高レベルにステップアップしていくという勉強方法を好む方にとっては良い慣習だと思います。
これのnginx版があると良いなぁと思っていたのですが、初学者目線からすると中々そのような記事等を見つけられませんでした。
なので、nginx版の`Hello world`を作成し、私のような初学者に感動を共有できればなぁと思い書き始めました（ちなみに初投稿です）。

# 前提
nginxはインストール済みとさせて下さい。
また、OSはMacとさせて下さい。

# やってみる

###　準備
まず、お好きな場所に以下のような構造を持つファイル群を作成して下さい。
内容は何でも構いませんが、面倒だと思うのでhtmlファイルの方は例を張っておきます。

```
data
├── images
│   └── example.png
└── www
    ├── 40x.html
    ├── example.html
    └── index.html
```

```html:index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>tutorial of nginx</title>
</head>

<body>
    <h1>nginxの練習です</h1>
</body>

</html>
```
```html:example.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>example page</title>
</head>

<body>
    <h1>Hello World!!</h1>
</body>

</html>
```
```html:40x.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Error page</title>
</head>

<body>
    <h1>Some Error happend.</h1>
</body>

</html>

```

### nginxの設定ファイルの編集
ここまでの準備ができたら後はnginxの設定ファイルを編集するだけです。
設定ファイルは`/usr/local/nginx/conf`, `/etc/nginx`, `/usr/local/etc/nginx`のいずれかのディレクトリ内に`nginx.conf`という名前で存在するそうです（私の場合は一番最後のケースでした）。
`nginx.conf`に対してまずは以下の内容をコピペして下さい。ちなみに、同じディレクトリに`nginx.conf.default`というファイルが有り、それをコピーすればいつでも最初の状態に復旧できるので安心して下さい。
その後、\<dataまでのパス\>の部分を個人の環境に合わせて編集して下さい。
（コメント書きまくったらコメントのほうが多くなってしまいました。。。笑）

```
# nginxの構成ファイルの基本４要素をモジュールと呼ぶ
# core, event, http, mailがモジュール

# 「ディレクティブ名 パラメータ;」 をまとめてディレクティブと呼ぶ
# 設定項目のこと
worker_processes  1;

# 中括弧を持つディレクティブはブロックディレクティブと呼ぶ
# 中身はコンテキストと呼ぶ

# eventsモジュールは省略不可
events {
    # ワーカープロセスが最大でいくつまでコネクションを処理できるかを指定
    worker_connections  1024;
}


http {
    # mime.types: MIMEタイプと拡張子の間の関係を記述
    # レスポンスの際にはmime.typesの記述に従って 拡張子 -> MIMEタイプ とマッピング
    include       mime.types;

    # 上でマッピングできなかった際にはしたのでマッピング
    default_type  application/octet-stream;

    # sendfile関数とやらがあるらしく、それの利用を許可するかどうかを指定
    # 込み入ってて難しい。。。
    sendfile        on;

    # クライアントの要求を待ってあげる最大時間
    # 65秒間要求がなければ接続を切断する
    keepalive_timeout  65;

    # serverディレクティブはhttpディレクティブ内に記述
    server {
        listen       80; # 80番ポートで待機
        server_name  localhost; # サーバの名前。リクエストのHostと比較される

        # ドキュメントルートを指定。指定された場所がサーバーでの配信対象になる
        root <dataまでのパス>/data;

        # URLのパスをサーバー上のパスにマッピングする
        location / {
            # rootの場合はlocationのパラメータが最後に結合される
            # aliasの場合は結合されない
            root   <dataまでのパス>/data/www;
        }

        # localhost/images/と指定された場合、上のlocationと下のlocation２つにマッチング
        # その際には前方一致でより長くマッチングするほうが選ばれる（マッチする/の数を長さとする？）
        # ex) localhost/images/の場合、上は長さ1, 下は長さ2なので下を選ぶ
        location /images/ {
            # rootなので<dataまでのパス>/data/images/とマッピング
            root   <dataまでのパス>/data;
        }

        # 40xのテキストフレーズが検出された場合、/40x.htmlを返す
        error_page   400 401 403 404  /40x.html;

        # /40x.htmlでマッチングを行う
        # = は完全一致
        location = /40x.html {
            root   <dataまでのパス>/data/www;
        }

    }
}
```

### コマンドを叩く
ここまできたら後はコマンドを叩くだけです。
コンソールを起動して以下のコマンドを叩けば完了です。

```
$ nginx
```

### 確認してみる

折角webサーバーを立ち上げてみたので、何かリクエストを投げてみましょう。
webブラウザで`http://localhost/index.html`と入力してみて下さい。
「nginxの練習です」と表示されていれば成功です。逆に、表示されない場合には設定ファイルの記述が間違っているので、頑張って確認してみて下さい。
他にも`http://localhost/images/example.png`と入力し画像が返されることを確認してみたり、わざと`http://localhost/nofile.html`のように入力してみて404エラーが返されることを確認してみると楽しいと思います。
ちなみに、設定ファイルに何らかのミスが有ることが判明した際には、編集後に以下のコマンドを叩いてください。
nginxに対して変更が反映されます。

```
$ nginx -s reload
```

### nginxを停止させる

起動させたら停止させなければなりません。停止のためのコマンドは以下の2通りあります（本当はもっと色々な方法がある感じがしていますが、nginx純正の停止方法はこれらだと思います）。

```
$ nginx -s stop
```
```
$ nginx -s quit
```
英単語的に一緒なような気がして、何が違うの？と思いましたが、どうやら前者はいわゆるシャットダウンで、このコマンドを実行したらすぐに停止するようです。公式だと**fast shutdown**とよんでいます。
それに対して、後者はグレースフルシャットダウンと言い、このコマンド実行時にクライアントから届いたリクエストに関して捌き終わったらシャットダウンするそうです。公式でも**graceful shutdown**とよんでいて、どうやらnginxに限らない一般的な用語なようです。

# 終わりに
以上で「nginxで最小のwebサーバーを立ち上げてみる」は終わりになります。
立ち上げてみることは出来たでしょうか？
あまり力になれないかも知れませんが、もし全然出来ない場合などありましたらコメント頂ければ、時間に余裕のあるときに極力お返事させていただこうと思っています。
読んでいただいた方が少しでもnginxを勉強してみたいと思って頂けたら私としては嬉しいです。
最後に、ここまで読んで頂きありがとうございました！

# 参考文献
[1]. "Beginner's Guide", Nginx, http://nginx.org/en/docs/beginners_guide.html, 2020年11月30日参照