個人開発だと、1個のVPSやEC2インスタンスに多数のWebサービスを同居させている人も多いと思います。
今回はその際に
- 80番ポートでリッスンするNginxリバースプロキシ
- ホスト内に配置された複数のWebサービス
を全てdocker-compose化したところかなり便利だったので構成を紹介したいと思います。
例として作るもの
- 80番ポートでリッスンするリバースプロキシNginx
- WordPress A (foo.com)
- WordPress B (bar.com)
という3つをそれぞれ別のdocker-composeで起動し、リバースプロキシNginxから各WordPressへのアクセスをプロキシします。
(紹介したいのはdocker-composeの繋げ方なのでWordPressであることはあまり関係ありません。)
こちらがGitHubに置いたサンプル構成です。
(紹介用にまとめたので最初の3つのディレクトリは本来別のリポジトリで管理すると思います。)
構成図
構成図としてはこのような感じになります。
緑の四角で囲まれたのが一つのdocker-compose、オレンジの四角が一つのコンテナ、黄色の四角はポートバインドです。
これで理解できた人はもう以下を読む必要ありません(笑)
以下各ディレクトリについて説明します。
Nginx
リバースプロキシ用Nginxです。
これがホストの80番ポートでHTTPアクセスを受け、リクエストされたアドレスに応じてホストのそれぞれのポートにプロキシします。
foo.com.confとbar.com.confはほぼ同じですがupstreamのポートが分かれています。
リバースプロキシのDocker Composeのコツ
この構成でNginxは [ホストのIP]:[各サービスのポート] に対してサイトごとリクエストをプロキシしなくてはならないので、ホストのIPを知る必要があります。
しかし、Dockerは1つのcomposeに1つのネットワークを作りIPアドレス空間を振りますが、そのIP空間はデフォルトだと変動します。
なのでここで以下のように
version: '3'
services:
nginx:
image: nginx:alpine
ports:
- '80:80'
networks:
nginx_net:
ipv4_address: 172.16.0.2
volumes:
- ./conf.d:/etc/nginx/conf.d
networks:
nginx_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.0.0/24
networks:内でサブネットのアドレス範囲を指定することで、subnetが172.16.0.0/24ならばホストは172.16.0.1となり、これをNginxの設定に固定で書くことができます。
foo.com / bar.com
内容は同じで、ホストにバインドするポートの番号が違うだけです。
このポート番号をリバースプロキシNginxのconfファイルのupstreamと合わせることでアクセスを振り分けます。
srcフォルダにWordPressのソースファイルを入れてください。
静的ファイルはNginx、PHPスクリプトはphp-fpmが担当するので厳密には両方が全部をマウントする必要はないですが、しても問題ないのでそういています。
まともなWebサービスで静的ファイルはS3からとかやるときはちゃんと設定してください。
mysqlのデータはmysql/dataを/var/lib/mysqlにマウントすることで永続化されます。
またSSH経由で外部からメンテしやすいようにmysqlのポートもホストとバインドしています。
これもそれぞれのサービスでかぶらないようにしてください。
動かしてみる
上記リポジトリをcloneしてnginx、foo.com、bar.comのそれぞれのディレクトリで
docker-compose up -d
(-dはデーモンモード。動作確認するだけなら付けなくてもいいです)
でそれぞれを起動。
アクセスするローカルマシンのhostsファイルでfoo.comとbar.comのIPをサーバのものにしてブラウザでアクセスすると、WordPressのインストール画面が表示されるはずです。
サイトを増やす時
既存のサービスとかぶらないポートでをバインドしたdocker-composeを増やし、リバースプロキシNginxのconfを増やしてupstreamのポートを合わせるだけです。
コメント