suin.io

VirtualHostをお手軽に実現できるDockerコンテナnginx-proxyの起動方法

suin2016年7月21日

nginx-proxyはDockerでHTTPサーバのVirtualHostを実現するためのリバースプロキシです。これ自体もDockerコンテナとして起動できます。利用シーンとしては、1つのDockerホストに複数のウェブアプリを起動するときに用います。

nginx-proxyをDockerホストで起動しておけば、特にnginx-proxyにリンクしていないHTTPサーバコンテナでも、自動的にバーチャルホスト名でアクセスできるようになります。バーチャルホスト名を与えられる側のコンテナは-eVIRTUAL_HOSTというキーがあり、EXPOSEもしくは--expose80などのポートが空いていれば自動的に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.crtfoo.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をずっと起動しているとログが溜まってしまい、ディスクフルになってしまうので、デフォルトのロギングドライバを使う場合は上限値を設けるようにします。

RELATED POSTS