2018年9月28日金曜日

NGINX の proxy_pass のちょっとだけメモ

NGINX の proxy_pass で GET リクエストがどうなっちゃうのかいつもわからなくなるのでメモ。

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

まぁ全ては上記の NGINX に書いてあるんだけど、ここでは前方一致のやつだけ。

  • proxy_pass に URI が含まれる場合
  • location /name/ {
        proxy_pass http://127.0.0.1/remote/;
    }
    上記の NGINX ドキュメントページにおける「URI」という用語はどうも NGINX における $uri と同じで、ホスト名より後ろの文字列のようだ。上記例だと /remote/ という部分と思われる。

    この場合は、normalized URI (URI のデコード後: // を / にしたり %xx をデコードしたり)の location に定義した部分に一致する箇所を、proxy_pass て定義した URI 部分に置き換えて後ろのサーバに渡す模様。上記設定例の場合は例えば以下のようになる。
    http://www.example.com/name/foo?bar=baz

    http://127.0.0.1/remote/foo?bar=baz
    (/name/ を /remote/ に置き換えて GET リクエストはそのまま)

  • proxy_pass に URI が含まれない場合
  • location /some/path/ {
        proxy_pass http://127.0.0.1;
    }
    上記 NGINX ドキュメントには、proxy_pass に定義された値がホスト名部分で終わっちゃう場合は request uri ($request_uri)をそのまんま後ろのサーバに渡すって書いてある(または完全な normalized URI = $uri)。

    つまり上記設定例の場合は以下のような感じ。
    http://www.example.com/some/path/foo?bar=baz

    http://127.0.0.1/some/path/foo?bar=baz
    (ホスト名の後ろからはそのまま)

  • proxy_pass で変数を利用している場合
  • location /name/ {
        set myhost myhost.example.com;
        proxy_pass http://$myhost/;
    }
    この例のように proxy_pass 内で変数を利用してしまうと proxy_pass に指定した値のまま後ろのサーバに渡してしまう。つまり:
    http://www.example.com/name/foo?bar=baz

    http://myhost.example.com/
    (とにかく proxy_pass で指定したものしか渡さない)
    もしリクエストを渡したい場合、proxy_pass は以下のようにすれば良いだろう。
    proxy_pass http://$myhost$request_uri;

2018年9月20日木曜日

Dockerfile の EXPOSE もしくは docker run --expose の意味

どこのサイトとは言わないが、docker の EXPOSE について誤った情報が蔓延しているような気がしてならない。

そのサイトは docker0 で繋がっているコンテナ同士の通信のために EXPOSE が必要と書いている。つまり EXPOSE しないと他のコンテナからそのポートにアクセスできないということを言っている。

しかし Dockerfile に EXPOSE なんて書かなくても(docker run で --expose を与えなくても)、あるポートを listen しているコンテナに対して他のコンテナから接続することは可能だ。

嘘だと思うなら以下のような Dockerfile から作ったイメージを --expose せずに docker run して、他のコンテナから「nc -vz <相手> 8080」でもしてみるといい。普通に connected になるはず。
FROM fedora:28
RUN dnf install -y nc
ENTRYPOINT ["/usr/bin/nc", "-kl", "8080"]

私の EXPOSE の理解は以下。間違ってたらコメント等で指摘ください。

EXPOSE で指定されたポートは docker run に -P (--publish-all) を付与した際の対象ポートとなる。つまりコンテナ内のポートを -P でホストの任意ポートにマッピングしたい場合にEXPOSE でポートを明示する必要がある。