背景
別にどうでもいいという人はすっ飛ばして下さい。
とあるシステムの再構築をやっていた際に、統一された環境としてDockerを採用し
ローカルではdocker-compose、検証・本番ではAWS ECSに構築するということを行いました。
このシステムは、複数サービスに分割されているために、複数コンテナを立ち上げてそれぞれにルーティングしていますが、一部では下記のように/service_aにアクセスした場合にAのサービスへアクセスするといった作りになっていました。
ALB
├── a.hoge.com
│ └── Server A (source A)
├── b.hoge.com
│ └── Server B (source B)
└── c.hoge.com
├── Server C (source C)
└── c.hoge.com/fuga
└── Server C (source D)
要はSource CとDが同じサーバー上で動いているというわけです。
コンテナは分けたいなぁと思い下記のような構成する方針としました。
AWS上
ALB
├── a.hoge.com
│ └── Container A (source A)
├── b.hoge.com
│ └── Container B (source B)
└── c.hoge.com
│ └── Container C (source C)
└── c.hoge.com/fuga
└── Container D (source D)
ALBは簡単に設定ができます。
ローカルではALBは使えないので、代わりにjwilder/nginx-proxyを使っています。
jwilder/nginx-proxyはdocker-compose.yml上の各コンテナの環境設定部分にVIRTUAL_HOSTを書くと勝手にリバプロを設定してくれる
という便利なものです。
がしかし、nginx-proxでリバプロを上記のような設定を行う方法をググっても見当たらず…
そういうことができるようにしてくれ!とGit上でやりとりしているのがみつかっただけでした。
結果、Forkされたもので、VIRTUAL_HOSTとVIRTUAL_PATHを設定すればできるということを行っていましたが、それが本家には取り入れられていませんでした。
自前で全部書くしかないかと…と半ばあきらめてjwilder/nginx-proxyのコンフィグテンプレを呼んでいたら…
なんと、方法をみつけました。
方法
結論から言うと、VIRTUAL_HOSTで設定した名前のConfigを、とあるディレクトリに格納すると勝手にインクルードして設定を反映してくれます。
docker-compose.yml
nginx-proxy:
image: jwilder/nginx-proxy
privileged: true
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./docker/proxy/c.app.local:/etc/nginx/vhost.d/c.app.local
app.a:
build:
context: .
dockerfile: ./docker/app/Dockerfile
environment:
- VIRTUAL_HOST=a.app.local
volumes:
- ./src/a:/var/www
depends_on:
- mysql
app.b:
build:
context: .
dockerfile: ./docker/app/Dockerfile
environment:
- VIRTUAL_HOST=b.app.local
volumes:
- ./src/b:/var/www
depends_on:
- mysql
app.c:
build:
context: .
dockerfile: ./docker/app/Dockerfile
environment:
- VIRTUAL_HOST=c.app.local
volumes:
- ./src/c:/var/www
depends_on:
- mysql
app.d:
build:
context: .
dockerfile: ./docker/app/Dockerfile
environment:
- VIRTUAL_HOST=d.app.local
volumes:
- ./src/d:/var/www
depends_on:
- mysql
./docker/proxy/c.app.local:/etc/nginx/vhost.d/c.app.local
ここでnginx-proxy上のvhost.dにc.app.localファイルをマウントします。
app.dの設定は、内部でupstreamの設定をしているために、記載しておいてください。
(コンテナ名でもいけると思うけど未検証)
c.app.local
読み込ませたいホスト名をファイル名にします。
ちなみにlocation内に読み込ませる場合は、ホスト名_locationとすると内部にインクルードします。
location ^~ /fuga {
proxy_pass http://d.app.local/;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
client_max_body_size 0;
}
トレイリングスラッシュがあると、fugaのパスを無視してルーティングしてくれます。
ないと、http://d.app.local/fugaというアクセスになります。
上記だけで、http://c.app.local/fugaでアクセスした場合は、dのコンテナにルーティングされ
http://c.app.local/fuga以外でアクセスした場合は、通常通りcのコンテナにルーティングします。
これで解決。
あーよかったよかった。