ローカルのDockerで複数サービスを動かしproxyでドメインを捌くようにしてみた

docker
先の記事(Vagrant上で動かしてた開発環境をDocker上で動かすようにしてみた(メモ))では、AサービスとBサービスが動いている状況でAサービスのdocker-compose.ymlにproxyの設定を書いていました。まあそれでも良いんですけど、これだとA/B両方が同じネットワークで同じサービスとして動いてしまいます。どうしようかなと考えていたところ、参考になりそうな記事を見つけたのでそれに倣って設定してみました



参考にしたのはこちらの記事。


1サーバーに複数のコンテナ(サービス)を綺麗に乗せられるDockerってすごい便利です。こんなことがしたい。

四角で囲まれている部分が1サーバー、例えばlocalhostだったりAWSやGCPの1インスタンスだったりということです。
service-a.hoge.comにアクセスするとcontainer Aのサービスを利用できて、service-b.hoge.comにアクセスするとcontainer Bのサービスが利用できるという世界。

【Docker】複数のコンテナ(サービス)を1サーバーで起動させてサブドメインで80ポートにアクセスする – Qiita


なるほど!ネットワークをそれぞれ独立させた上で、それぞれのネットワークからも隔離された場所にproxyを設定するイメージにすれば3つのサービスがDocker上で共存かつ連携出来るというわけか。上の記事の図を参考に僕の環境の概念図を作成するとこんな感じ。


ネットワーク概念図





2つのサービス「A」「B」があって、端末からのアクセスはDockerのデフォルトネットワークを通してproxy(nginx)が引き受け、ドメインごとにネットワークを振り分けるという感じ。「A」「B」のappのみproxyからの接続を受けるために「proxy network」に属しています。一方でDBやMemcachedなどバックグラウンドのサーバ群はappからアクセス出来れば良いので、「proxy network」には属さずそれぞれのネットワーク(「A network」など)のみに属しています(詳細な設定は上で紹介した記事を参考にしてください)。



設定上のメリット

この設定のメリットはproxyをサービスから独立させることで docker-compose.yml のメンテナンスが簡単になると共に、3つ目以降のサービスの追加が容易になる点になります。最初にproxyを設定したときはproxyサーバの設定がサービスAに載っていたので、サービスAを起動しないとサービスBに繋がらないということになっていて少々煩雑でした。

また僕の環境ではproxyにはオレオレ証明書が設定してあって、「A」「B」両方ともSSLの設定をすることでそれぞれ「https://local.a-service.com」「https://local.b-service.com」みたいな形でアクセスが可能になっています。将来3つ目のサービス「C」を作成した時もこの設定は有効なので、簡単な設定で「https://local.c-service.com」への接続を行うことが出来ます(「local.c-service.com」を含んだ証明書を再発行する必要があります)。



設定上の注意点

理由はよく解りませんが、サービスA、サービスBのDBのportを両方「13306:3306」に設定していたら「重複しているから起動できない」と怒られました。違うネットワークでもダメなのか。仕方がないのでサービスBのDBのportを「23306:3306」に設定してやったら問題なく起動できるようになりました。