Nginxでリバースプロキシするメモ

ちょい悩んだのでメモ。以下の記述は間違いが含まれているかもしれません。

やりたいこと

いま、http://a.comとhttp://localhost:12345/がある。

これを、http://localhost/a/topというアドレスでアクセスしたときはhttp://a.com/topとなるようにして、http://localhost/b/topというアドレスでアクセスしたときはhttp://localhost:12345/topになるようにしたい。

つかったのはNginx + Windows。windowsでもインストール不要でサクサク動くので良い。コマンドでlinuxと同じように操作できるのが良い。windowsにインストールされるapacheはサービスになったりごちゃごちゃ便利そうで便利じゃないことしまくるので好きじゃない。

やり方

参考にしたページは以下。

Nginx reverse proxy + URL rewrite

下記のような感じにすればよい。

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

/fooというlocationにアクセスがあったら、/foo/以降のURLを取り出してそれで上書きする。そいで、http://localhost:3200に飛ばす。proxy_redirectはLocationとRefreshを書きなおす設定。これ、defaultじゃないとあかん気がするのだけど。つまり、

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     default;
}

これで良いんじゃないの?ということ。実際、これでちゃんと動いているように思う。

proxy_set_headerはHostヘッダを書き換える設定のようだ。デフォルトだとプロキシ先のホスト名になる。上記例だとlocalhostになる。これをnginxが受け取ったリクエストのホスト名に書き直すのがこの設定。だと思う。私の理解が正しければ。

それをば、わざわざ前者のようにredirectをoffとした上でproxy_set_header Host $host;を書くのか。

両者の違いは、nginxの後ろにいるサーバからどう見えるか、である。nginxがfoo.comというドメインで動いているとしたとき、前者はバックに居る3200ポートで待っているサーバがHostにfoo.comが入ったリクエストを受け取るのに対し、後者はlocalhostがHostに入ったリクエストを受け取る。

前者でも後者でも外部からfoo.comにアクセスする人から見れば違いは無いのだけど、もしHostを読み取ってゴチャゴチャなにかやる処理をしているとどのホストとしてアクセスしてきてもlocalhostしか取れないから失敗するだろうし、それ以前になんか気持ち悪いのでやっぱり前者の方が良さそう。