nginxのconfの設定手順の正しいプロセス

「正しい」と書いちゃってるけど、仕事の現場として正しいプロセスというのは存在する。「正しくない」プロセスというのは一気に設定しすぎてどこでトラブってるかわ辛くなっちゃうこと。

### サマリー

- nginxが起動してないことを確認
- curlで80番ポートにアクセスして失敗することを確認
- nginxを起動させる
- curlで80番ポートにアクセスして成功することを確認
- proxy_passを設定して、curlの80番にアクセスして失敗することを確認
- アプリケーション・サーバー（8080ポートで起動）を起動してアプリケーション・サーバー単体で稼働していることをcurlコマンドで8080にアクセスして確認
- curlの80番にアクセスして成功することを確認

### まずnginxが起動してないことを確認しましょう

topコマンドやps aux | grep nginx とか、pgrep とかで確認しましょう。

起動してないことを確認した後に、curlでエラーが帰ることを確認します。もし何かレスポンスが帰ってきちゃったらそれは、既に別のWebサーバーが起動しているということです。

```
$ curl localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
```
で何もかえって来ないことを確認します。

次にnginxを起動しましょう。

```
nginx
```

起動方法は他にもあるでしょうが、ここではnginxコマンドで起動しています。

起動したら、80でlistenしているかどうかを確認します。

```
# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

webcomeページが開かれました。ブラウザでレスポンスを確認してる例がありますが、curlコマンドでテストをする習慣をつけましょう。本当にクラウドサーバーを設定する際には、FWやセキュリティの設定などで手元のブラウザではアクセスできないこともあります。ローカルマシンからローカルマシンのnginxならほぼ確実にアクセスできます。経路が増えれば増えるほど別の障害が発生します。単体での稼働を確認しましょう。

### proxy_passを設定し、エラーがでることを確認する

nginx単体で動かすということはあまりなくて、ほぼ何かしらのアプリケーション・サーバーにプロキシするという使い方が多いと思います。そこで使うのはproxy_passディレクティブです。

```
location / {
    proxy_pass http://127.0.0.1:8080;
}
```

この段階ですべての通信が8080ポートに渡ります。アプリケーション・サーバーに繋げばアプリケーション・サーバーからのレスポンスが表示されるはずですが、アプリケーションサーバーを起動してない状態でエラーがでることを確認しましょう。

設定ファイルを保存してnginxをリロードしたらエラーになるはずです。

```
$ nginx -s reload
$ curl localhost
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>
```

502エラーがでました。まずアプリケーション・サーバーを起動してないとエラーがでるということが大事です。

### アプリケーション・サーバーを起動する

次にアプリケーション・サーバーを8080のポートで起動します。本当はRailsなどアプリケーションが完成していればいいですが、設定段階では完成してるかどうかがわかりません。また作り込まれた本物アプリケーションは依存モジュールも多く確実に起動しているかどうかも怪しいです。なので、ワンライナーで確実に起動するアプリケーション・サーバー（実質Webサーバー）を起動します。

「ワンライナー Webサーバー」でググって出てくるスクリプトをコピペして起動します。ワンライナーを使うのは環境を汚したくないからです。そのOSにインストールされてる最小限のライブラリのみで実行します。下記の例ではディレクトリを公開するワンライナーを使っていますが、害の無いディレクトリでテストをしてください。

まだnginxからアクセスしちゃダメです。まず8080のポートでアクセスします。

```
$ curl localhost:8080
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
...
```

これで8080のポートで何かしらのWebサーバー（アプリケーション・サーバーとして想定）が起動しています。なのでproxy_passは通ってるはずなので、改めてnginx経由の80番ポートでアクセスしましょう

```
# curl localhost
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
...
```

同じ結果が帰ってきます。80番ポートでアクセスするとlocalhostの8080にプロキシされてることが確認できました。めでたし。「失敗していたのが」「私のこの作業により」「成功しました」の3段構えがすべてにおいて大事です。

### UNIXドメインソケットではなくTCP/IPを選ぶ理由

nginxのproxy_passディレクティブではUNIXドメインソケットの例をよく見ます。同一マシン内での通信ですので、原理的にはUNIXドメインソケットのほうが速いはずですがその差は僅かで他の処理の遅さに隠れるレベル。またUNIXドメインソケットは擬似的なファイルを作り、その「置き場所」「権限」に関して初心者はミスりがち。さらにアプリケーション・サーバーをUNIXドメインソケットで起動した場合って、ブラウザ単体でアクセスできない。「単体での品質が保証できない」というのは初心者殺しすぎるのでおすすめはしないです。(curlコマンドならunixドメインソケットで起動したサーバにもアクセスできるけどあまり知られてない)

「密結合の方が速いけど単体の品質保証が難しい」V.S.「疎結合の方が遅いけど単体の品質が保ちやすい」という戦いなので、まずは疎結合からスタートするというのがエンジニアリングにおいては大事です。

そもそもインターネット自体が、HTMLとJavaScriptとCSSと画像がバラバラに飛んできて後でつなげるというめちゃくちゃ効率の悪い方法で構築されてる。当然1ファイルでやった方が効率がいいよねということでHDMLという複数の要素を1ファイルに収める規格があったけど全然受け入れられることは無かったですね。

時代とともに「バラバラのファイルだけどそれでも通信規格側が並行して流せるようにする」方向に進化してくるので、人間様には優しく疎結合をしたままでも機械側が力技で速くしてくれるというのがテクノロジーの進化です。