Table of contents
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サーバーと思わせ実はリバースプロキシなコンテナを立てるという形にしてみました。
図
インターネット │ │Port443 │ ┌───│───── Linux PC ────────────────┐ │ │ │ │ ┌┴─────────┐ ┌────────────┐ │ │ │jwilder/nginx-proxy │ │jrcs/letsencrypt-・・ │ │ │ │SSLアクセラレータ │ │Let's Encrypt 取得/更新 │ │ │ │(リバースプロキシ)│ │ │ │ │ └┬─────────┘ └────────────┘ │ │ │ │ │ │Port80 │ │ │ │ │ ┌┴───────────────────┐ │ │ │nginx │ │ │ │Webサーバーと思わせ実はリバースプロキシ │ │ │ └┬───────────────────┘ │ │ │ │ └───│──────────────────────────┘ │ │Port80 │ ┌───│───── Windows PC ───────────────┐ │ │ │ │ ┌┴──────────┐ │ │ │Webサーバー IISとか │ │ │ └───────────┘ │ │ │ └──────────────────────────────┘
こんな感じで、見ての通り余計なプロキシが1つ挟まっています。
いささか非効率なのは否めませんが、一応期待通りに動作していることと、手間を少なくということで、割り切ってます。
docker-compose.yml
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:
nginx-proxy/custom.conf
# バージョン情報を非表示 server_tokens off; # クライアントリクエストボディ上限を無制限 client_max_body_size 0;
bridge-1/default.conf
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; } }
よもやま
- 常時SSLが常識のようになっていますので、無料で証明書を発行してくれる Let's Encrypt の存在はスバラシイです。
- Let's Encrypt はワイルドカード証明書も発行できるようなので、そっちを狙いたいところですが、DNSテーブルを書き換える必要があります。
証明書の更新時にも新たに書き換える必要があるので、APIが提供されているようなDNSサーバーなら不可能ではないですが、自動化はかなり手間です。
が、今回のこの環境であれば、サブドメインを使いたい場合にもコンテナ一つ増やすだけで済むので、無理にワイルドカード証明書を使わなくても良さそうに思います。
- Let's Encrypt はワイルドカード証明書も発行できるようなので、そっちを狙いたいところですが、DNSテーブルを書き換える必要があります。
- 昨今はクラウド環境が充実してて、わざわざ自前でSSLアクセラレータ環境を作る機会も減ってきてるとはおもいますが、それでもまだ必要なケースはあります。
Let's Encryptや、それを簡単につかえるdockerイメージの作者様、使い方を公開しておられる皆様には感謝です。ありがとうございます。
Page Info | |
---|---|
Page Name : | 技術系備忘録/Docker/SSLアクセラレータ&リバースプロキシ |
Page aliases : | None |
Page owner : | takatsuka |
Can Read | |
Groups : | All visitors |
Users : | All visitors |
Can Edit | |
Groups : | No one |
Users : | No one |
Counter: 5429,
today: 1,
yesterday: 4
Princeps date: 2020-06-01 (Mon) 17:24:51
Last-modified: 2020-06-01 (Mon) 17:24:51 (JST) (1562d) by takatsuka