nginx-proxyはDockerでHTTPサーバのVirtualHostを実現するためのリバースプロキシです。これ自体もDockerコンテナとして起動できます。利用シーンとしては、1つのDockerホストに複数のウェブアプリを起動するときに用います。
nginx-proxyをDockerホストで起動しておけば、特にnginx-proxyにリンクしていないHTTPサーバコンテナでも、自動的にバーチャルホスト名でアクセスできるようになります。バーチャルホスト名を与えられる側のコンテナは-e
にVIRTUAL_HOST
というキーがあり、EXPOSE
もしくは--expose
で80
などのポートが空いていれば自動的にnginx-proxyに検知されます。
docker run -e VIRTUAL_HOST=foo.bar.com php
Dockerでコンテナ同士で通信するとなると、明示的にlinks
することが普通ですが、nginx-proxyはDockerのRemote APIで他のコンテナの起動・停止を監視し、起動を検知したら勝手にリンクしてくれるので、ユーザがわざわざリンクする必要がないのです。
nginx-proxyの起動方法
nginx-proxyは基本的にdocker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
で起動すればOKなのですが、実際プロダクションで運用するとなるとどういう設定で起動したほうがいいかですが、僕としては次のコマンドで起動することが多いです。
docker run \
--detach \
--name nginx-proxy \
--publish 80:80 \
--publish 443:443 \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
--volume /certs:/etc/nginx/certs:ro \
--restart always \
--log-opt max-size=5m \
--log-opt max-file=10 \
jwilder/nginx-proxy
すこしパラメータの意味について書きます。
--publish 80:80
, --publish 443:443
ポート80とポート443をDockerホストに公開します。つまり、HTTPとHTTPSのデフォルトポートを公開するわけで、nginx-proxyがあるDockerホストでは他のHTTPサーバは80ポートなどを使えなくなり、nginx-proxyのバックエンドサーバとして起動するような運用になります。
--volume /var/run/docker.sock:/tmp/docker.sock:ro
このパラメータは、nginx-proxyがDockerのコンテナ起動・停止などのイベントをDocker Remote APIを使い受け取れるようにするためにマウントします。nginx-proxyはコンテナ起動・停止を検知すると、Nginxの設定ファイルを追加・削除、そして設定の読み込み処理を走らせます。
/var/run/docker.sock
をマウントするとコンテナからDockerの操作がいろいろできてしまうので、セキュリティ的に怖いですが、なるたけリスクを軽減するために読み取り専用のro
オプションをつけます。
--volume /certs:/etc/nginx/certs:ro
Dockerホストに置いたSSL証明書をnginx-proxyで参照するためにマウントします。foo.bar.com.crt
、foo.bar.com.key
のように、バーチャルホスト名.crt
・バーチャルホスト名.key
といった命名規則でSSL証明書を配置しておくとnginx-proxyがよしなに読み込んでくれます。
--restart always
これはnginx-proxyをプロダクションで稼働することを想定した設定で、万が一nginx-proxyが異常終了しても起動がかかるようにするオプションです。
--log-opt max-size=5m
, --log-opt max-file=10
これもプロダクションで運用するためのログの上限を設定するオプションです。nginx-proxyをずっと起動しているとログが溜まってしまい、ディスクフルになってしまうので、デフォルトのロギングドライバを使う場合は上限値を設けるようにします。