#はじめに
Docker使ってますか?同一ホストに簡単に複数のアプリケーション環境を起動することができて便利ですよね。
しかし、複数のコンテナを起動した際に悩ましいのがポートマッピング問題・・・。
- ホスト側の空きポートを明示的に指定してあげる必要がある
- ブラウザからアプリケーションへのアクセスは、可能な限り80番を使いたい
これらの問題を、nginxで(動的に)リバースプロキシを設定し、任意のサブドメイン等からコンテナにアクセス可能にさせてくれるDockerイメージが jwilder/nginx-proxy です。
#アプリケーションのポートマッピング例
以下のような、docker-compose.ymlファイルの場合
version: '3'
services:
web:
image: web
ports:
- "80:80"
web2:
image: web2
ports:
- "8080:80"
web3:
image: web3
ports:
- "9000:80"
※わかりやすいように、オプションは一部割愛
webコンテナへのアクセスは、ポート80番なので http://ホスト
等でアクセスすることができるが、例えばweb2へアクセスする際は http://ホスト:8080
のように、ポート番号を付与する必要が出てくる。
#リバースプロキシ設定
実際にリバースプロキシを設定していきます。設定は簡単で、docker-compose.ymlに、jwilder/nginx-proxy をイメージに指定したリバースプロキシ用コンテナを追加し、リバースプロキシを設定した各コンテナに対し、環境変数VIRTUAL_HOSTを与えてあげるだけです。
version: '3'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
web:
image: web
environment:
- VIRTUAL_HOST=web.localhost
web2:
image: web2
environment:
- VIRTUAL_HOST=web2.localhost
web3:
image: web3
environment:
- VIRTUAL_HOST=web3.localhost
上記のように設定し、docker-compose up すれば、VIRTUAL_HOSTに設定したサブドメインでブラウザからアクセス可能になります。これならポートを意識する必要がありません。
#ポイント
##同一ネットワーク上に起動させる
設定例ではネットワークを指定していませんので、docker-composeによって生成されるネットワークに属することになりますが、nginx-proxyコンテナと、リバースプロキシ対象のコンテナを別々で起動させる場合は、明示的に同じネットワークを指定してあげる必要があります。
##exposeでアプリケーションが利用されるポートを指定
各サービスのexposeオプションを指定しなかった場合は、デフォルトで80番ポートに接続しようとするので、80番以外で接続させる場合は、exposeで該当ポートを指定してあげる必要があります。
#その他
##追加でコンテナを起動してもリバースプロキシしてくれる
nginx-proxyコンテナがネットワーク上のDockerコンテナの起動を検知し、後から追加されたコンテナに対してもしっかりリバースプロキシを設定してくれます。
##アクセス制限
環境変数にNETWORK_ACCESS=internal
が指定されているコンテナに対し、nginx-proxyコンテナ内の/etc/nginx/network_internal.conf
に記述された設定に基づいてアクセス制限を設定することができます。
allow 10.0.2.2;
deny all;
ホスト側で用意した上記ファイルをnginx-proxyコンテナへマウントします。
version: '3'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./network_internal.conf:/etc/nginx/network_internal.conf
web:
image: web
environment:
- VIRTUAL_HOST=web.localhost
web2:
image: web2
environment:
- VIRTUAL_HOST=web2.localhost
- NETWORK_ACCESS=internal
以上のように設定すると、web2は10.0.2.2
からのみアクセス可能なコンテナになります。
##その他、転送可能データサイズの変更やタイムアウト時間設定
nginx-proxyコンテナ内/etc/nginx/conf.d
ディレクトリ配下に置かれた設定ファイルを読み込むので、ホスト側で設定ファイルを用意して以下のようにコンテナ内にマウントしてあげれば良いです。
version: '3'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf
web:
image: web
environment:
- VIRTUAL_HOST=web.localhost
#おわりに
ローカルでの検証にはもちろん、Dockerコンテナが動的に増減するようなサービスで大いに役立ちます。感謝です。上で紹介した機能以外にもいくつか便利な機能を有していますので、GitHubのREADMEをご参照ください。
###参考ページ