Back to page

− Links

 Print 

技術系備忘録​/Docker​/SSLアクセラレータ&リバースプロキシ :: シンクリッジ

xpwiki:技術系備忘録/Docker/SSLアクセラレータ&リバースプロキシ

Table of contents
  • docker-compose ファイル一覧
    • docker-compose.yml
    • nginx-proxy/custom.conf
    • bridge-1/default.conf
  • よもやま

SSLアクセラレータ兼リバースプロキシの docker-compose です。

この用途ではかなりメジャーな jwilder/nginx-proxy と jrcs/letsencrypt-nginx-proxy-companion というdockerイメージを利用しています。
少しの設定を書くだけで Let's Encrypt の証明書の取得と更新を自動でやってくれるのでメンテフリー(と言うと大げさですが)な HTTPS の webサーバー環境が作れてしまいます。
スバラシイです。

というわけで自分も使ってみようと思たのですが、ちょっと困ったことが・・。
今回の自分のケースでは、webサーバーは既に別にあって、しかも Windows です。

jwilder/nginx-proxy、jrcs/letsencrypt-nginx-proxy-companion の場合、多分ですが、
Webサーバーは同じhostにdockerコンテナとして稼働していることが前提のように見受けられます。

証明書の設定などは Webサーバーコンテナの環境変数に記述するのが基本なようで、それ以外の方法を見つけられなかったです。ご存じの方おられましたら是非ご教示頂きたいです。

そこで、Webサーバーと思わせ実はリバースプロキシなコンテナを立てるという形にしてみました。

anchor.png[1]

   インターネット
        │
        │Port443
        │
┌───│───── Linux PC ────────────────┐
│      │                                                    │
│    ┌┴─────────┐  ┌────────────┐  │
│    │jwilder/nginx-proxy │  │jrcs/letsencrypt-・・   │  │
│    │SSLアクセラレータ   │  │Let's Encrypt 取得/更新 │  │
│    │(リバースプロキシ)│  │                        │  │
│    └┬─────────┘  └────────────┘  │
│      │                                                    │
│      │Port80                                              │
│      │                                                    │
│    ┌┴───────────────────┐            │
│    │nginx                                   │            │
│    │Webサーバーと思わせ実はリバースプロキシ │            │
│    └┬───────────────────┘            │
│      │                                                    │
└───│──────────────────────────┘
        │
        │Port80
        │
┌───│───── Windows PC ───────────────┐
│      │                                                    │
│    ┌┴──────────┐                              │
│    │Webサーバー IISとか   │                              │
│    └───────────┘                              │
│                                                            │
└──────────────────────────────┘

こんな感じで、見ての通り余計なプロキシが1つ挟まっています。
いささか非効率なのは否めませんが、一応期待通りに動作していることと、手間を少なくということで、割り切ってます。

Page Top

docker-compose ファイル一覧 anchor.png[2]

├ docker-compose.yml
├ nginx-proxy
│ └ custom.conf
└ bridge-1
  └ default.conf
Page Top

docker-compose.yml anchor.png[3]

version: '3'

services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    labels:
      - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true
    ports:
#     Let's Encrypt が証明書を発行する際、名前解決後にポート80で確認に来るので 80も通しておく必要アリ
      - 80:80
      - 443:443
    volumes:
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./certs:/etc/nginx/certs:ro
      - ./nginx-proxy/custom.conf:/etc/nginx/conf.d/custom.conf:ro
    restart: always

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    volumes:
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./certs:/etc/nginx/certs:rw
#   environment:
#     - NGINX_PROXY_CONTAINER=nginx-proxy      やり方が間違ってるんだと思うけど、
#     - NGINX_DOCKER_GEN_CONTAINER=nginx-proxy うまく探し出してくれないっぽいのでこのやり方はナシ
    restart: always

  bridge-1:
    image: nginx:latest
    volumes:
      - ./bridge-1/default.conf:/etc/nginx/conf.d/default.conf
      - ./bridge-1:/var/www/html
    environment:
      - VIRTUAL_PORT=80
#    ↓ 環境に合わせて変更のこと
      - VIRTUAL_HOST=example.com
      - LETSENCRYPT_HOST=example.com
      - LETSENCRYPT_EMAIL=info@example.com
    restart: always

volumes:
  vhost:
  html:
Page Top

nginx-proxy/custom.conf anchor.png[4]

# バージョン情報を非表示
server_tokens off;

# クライアントリクエストボディ上限を無制限
client_max_body_size 0;
Page Top

bridge-1/default.conf anchor.png[5]

server {
    listen 0.0.0.0:80;
    server_name localhost;

    location / {
#      ↓ 環境に合わせて変更のこと
        proxy_pass http://192.168.1.100:80/;
        proxy_redirect off;
        proxy_set_header Host            $http_host;
#       proxy_set_header X-Real-IP       $remote_addr; 設定既なのでココでは設定しない
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        client_max_body_size 0;
    }
}
Page Top

よもやま anchor.png[6]

  • 常時SSLが常識のようになっていますので、無料で証明書を発行してくれる Let's Encrypt の存在はスバラシイです。
    • Let's Encrypt はワイルドカード証明書も発行できるようなので、そっちを狙いたいところですが、DNSテーブルを書き換える必要があります。
      証明書の更新時にも新たに書き換える必要があるので、APIが提供されているようなDNSサーバーなら不可能ではないですが、自動化はかなり手間です。
      が、今回のこの環境であれば、サブドメインを使いたい場合にもコンテナ一つ増やすだけで済むので、無理にワイルドカード証明書を使わなくても良さそうに思います。
  • 昨今はクラウド環境が充実してて、わざわざ自前でSSLアクセラレータ環境を作る機会も減ってきてるとはおもいますが、それでもまだ必要なケースはあります。
    Let's Encryptや、それを簡単につかえるdockerイメージの作者様、使い方を公開しておられる皆様には感謝です。ありがとうございます。

Last-modified: 2020-06-01 (Mon) 17:24:51 (JST) (324d) by takatsuka