Fusicきばんブログ

Fusic基盤ユニットの非公式技術ブログ

nginx-proxy(Docker)で設定なしリバースプロキシ

こんにちは桜川です。

Docker便利ですね!

自分の開発環境はWebサーバーにアクセスするのに、前段にNginxでリーバースプロキシを設置してホスト名を切り替えてアクセスしてます。
この方法で基本困ってなかったのですが、地味にめんどくさいのがNginxへのリバースプロキシ設定の追加です。

コンテナ新規起動 => Nginxのリバースプロキシ設定の追加 => Nginx再起動

この設定1分あれば完了する。。。
けど、めんどくさい。。。
しかも、設定ファイルの管理もめんどくさい。。。

やっぱりあった

nginx-proxy を利用するとコンテナに起動・終了を検知して自動でリバースプロキシの設定を行ってくれます!
nginx-proxy 知らなかったよ。。。
ググってすらなかった。。。

github.com

jwilder/nginx-proxy

とりあえずhttpアクセスできるようにする

リバースプロキシを利用して、バックグラウンドにApacheを起動するにはこれだけでいい
httpd1.example.com httpd2.example.com はhostsファイルにでも設定しておいてください

  • nginx がリバースプロキシ用のコンテナ
  • httpd1 httpd2 がサンプル用にApacheを起動してます。
version: '3'
services:
  nginx:
    container_name: nginx
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
  httpd1:
    container_name: httpd1
    image: httpd
    environment:
      - VIRTUAL_HOST=httpd1.example.com
  httpd2:
    container_name: httpd2
    image: httpd
    environment:
      - VIRTUAL_HOST=httpd2.example.com
  • jwilder/nginx-proxy
    • nginx-proxyはコンテナの起動・停止イベントを受け取る必要がある為、 docker.sock をマウントする必要があります。
  • http
    • コンテナにアクセスしたいホスト名を VIRTUAL_HOST で設定します
    • アクセスする必要があるコンテナで expose しておいてください

ここまでは簡単でよかった。サクッと出来た

SSLを使おうとした場合にちょっと手間取りました

SSLアクセス用に証明書を設置する

SSLアクセスするためには、証明書を nginx-proxy コンテナ内の /etc/nginx/certsホスト名.key ホスト名.crt で設置しておく必要があります。
なんだけど、開発環境だしホスト名毎にSSL証明書を作るのはちょっと。。。

と思ってたらやっぱりありました。使用する証明書を選ぶ機能。
CERT_NAME を設定するとアクセスするときに使用する証明書を選択することが出来ます。
※設定しない場合は、 ホスト名.crt, ホスト名.key が使用される

version: '3'
services:
  nginx:
    container_name: nginx
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./certs:/etc/nginx/certs # ここに証明書を設置する
  httpd1:
    container_name: httpd1
    image: httpd
    environment:
      - VIRTUAL_HOST=httpd1.example.com
      - CERT_NAME=default # 使用する証明書名(default.crt, default.keyが使用される。)
  httpd2:
    container_name: httpd2
    image: httpd
    environment:
      - VIRTUAL_HOST=httpd2.example.com
      - CERT_NAME=default # 使用する証明書名(default.crt, default.keyが使用される。)

これでSSLアクセスできるようになった!
クリア!
と思っていたら、 http がすべて https にリダイレクトされている。。。
デフォルトでは自動でリダイレクトされるみたいです。

自動リダイレクトを無効にする

HTTPS_METHODnoredirect を設定することで自動リダイレクトを無効にできるようです。

version: '3'
services:
  nginx:
    container_name: nginx
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./certs:/etc/nginx/certs # ここに証明書を設置する
  httpd1:
    container_name: httpd1
    image: httpd
    environment:
      - VIRTUAL_HOST=httpd1.example.com
      - CERT_NAME=default # 使用する証明書名(default.crt, default.keyが使用される)
      - HTTPS_METHOD=noredirect # リダイレクトを無効にする
  httpd2:
    container_name: httpd2
    image: httpd
    environment:
      - VIRTUAL_HOST=httpd2.example.com
      - CERT_NAME=default # 使用する証明書名(default.crt, default.keyが使用される)
      - HTTPS_METHOD=noredirect # リダイレクトを無効にする

これで目的を達成!
めでたしめでたし。

まとめ

  • httpアクセスだけでよければ、 exposeVIRTUAL_HOST を設定するだけ
  • SSLアクセスする必要がある場合は証明書を設置する
  • 必要に応じて、 CERT_NAMEHTTPS_METHOD を設定する