LoginSignup
36
42

More than 5 years have passed since last update.

jwilder/nginx-proxyで{ホスト名}/{パス}でコンテナにルーティングする方法

Posted at

背景

別にどうでもいいという人はすっ飛ばして下さい。

とあるシステムの再構築をやっていた際に、統一された環境として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のコンテナにルーティングします。

これで解決。
あーよかったよかった。

36
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
42