やりたいこと
仮に example.com というドメインを取得していたとする。そのドメインに対してサブドメインを発行して、 hoge.example.com というドメインで hoge サービスを配信。また fuga.example.com というサブドメインを発行し、fuga サービスを配信。
このご時世なので、各サブドメインに対してSSL証明書も発行して、SSLで配信できるようにしたい、Let's Encrypt で発行するにしても、面倒なので自動で発行でできるようにしたい。
使うもの
上記の要件を満たせるものが、下記だ。
jwilder/nginx-proxy
これはコンテナと同じネットワークに存在するコンテナを監視し環境変数からドメインを取得しそのドメインにプロキシしてくれるものだ。 ベース技術としてdocker-genという設定ファイルをテンプレートから生成してくれるものを使っている。
※上記イメージはホストの/var/run/docker.sock をマウントして使用するため、不正利用の危険がありえます。使用する際には自己判断のもと自己責任でお願いします。
jrcs/letsencrypt-nginx-proxy-companion
こちらは、上記の nginx-proxy と連携して Let's Encrypt からSSL証明書を発行してくれるものだ。
また、環境は以下の通りだ。
$ docker version Client: Version: 18.05.0-ce API version: 1.37 Go version: go1.9.5 Git commit: f150324 Built: Wed May 9 22:14:54 2018 OS/Arch: linux/amd64 Experimental: false Orchestrator: swarm Server: Engine: Version: 18.05.0-ce API version: 1.37 (minimum version 1.12) Go version: go1.9.5 Git commit: f150324 Built: Wed May 9 22:18:36 2018 OS/Arch: linux/amd64 Experimental: false $ docker-compose version docker-compose version 1.21.2, build a133471 docker-py version: 3.3.0 CPython version: 3.6.5 OpenSSL version: OpenSSL 1.0.1t 3 May 2016
構成
まずホストの 80, 443 で LISTENするサービスとして docker-proxy (上記の nginx-proxy, letsencrypt-nginx-proxy-companion を立ち上げてくれる) docker-compose を作成。
この docker-compose でプロキシ用のコンテナと、SSL証明書の自動発行コンテナが作成される。また、プロキシしたいサービスはこのネットワークに属している必要があるので、名前をつけて指定しやすいようにしている。(ただしこれはcompose バージョン 3.5から使用可能なので注意)
ここまでで準備はおおよそ完了で、今度はプロキシして配信したいサービスの方の設定だ。
こちらはそんなに難しいことはない。 docker-compose.yml にnetworks にexternal に先ほどの docker-proxy で作成したネットワークの名前を指定する。 次にコンテナに環境変数を設定する。
- VIRTUAL_HOST
- プロキシする際の vhost に当たるもの、この名前でプロキシされるので任意のサブドメインを割り当てる。
- VIRTUAL_PORT
- プロキシする際のコンテナ側のポート。
- LETSENCRYPT_HOST
- Let's Encrypt で自動更新するホスト名。基本的には VIRTUAL_HOST と同じになるはずだ。
- LETSENCRYPT_EMAIL
- Let's Encrypt の更新時に使用するメールアドレスだ。
まとめ
これで、無事サービスが複数に増えても簡単にSSLでホスティングすることができそうです。 途中で、docker-composeのファイルバージョンの違いによる書き方の違いや、非推奨になっていたりとで少し手間取りました。