サーバ上でWebサーバを複数立てたい場合、WebサーバのnginxもしくはAppacheをインストールして、リッスンポートを開けて・・・といったことを複数回実施しないといけない。
更に今どき、インターネット公開する際にはhttps化はもはや必須。
そうなるとサーバ証明書を発行して、Webサーバに組み込んで・・・
みたいなことをWebサーバの数だけ実施しないといけないので、かなりめんどくさい。
それがdockerだと、手間なく、そして幾らでもWebサーバを作れるので
一つのサーバに複数Webサーバを立てたい時はかなり便利。
イメージにすると以下のような感じ。
AのWebサーバにアクセスしたい場合は「A.hogehoge.com」、
BのWebサーバにアクセスしたい場合は「B.hogehoge.com」といった具合に
サブドメインを変更するだけで、あとはよしなにリバースプロキシとhttps化を自動で行ってくれる。
そんな夢見たいな神ツールをdockerでイメージ提供されてるので、
Oracle Cloud上のUbuntuサーバで実装してみた。
あと、以前に書いたブログ記事の「Portainer」もこの方法でhttps化ができるので、後で紹介する。
Docker管理ツールPortainerで複数ホストをまとめて管理
ニッチなDocker管理ツールであるPortainerの紹介
前提
以下を準備すること。特に上2つは必須。
- パブリック公開可能なdockerホスト(ここではOCIのUbuntu)
- 独自ドメインとDNS編集可能な環境
- dockerの知識
- 運用したいWebサーバ(WordPressとかでもいいんじゃない?)
すでにホスト上にdocker環境は設定済みとする。
リバースプロキシ用コンテナ作成
docker-compose.ymlなりPortainerで以下のコードを書いて、コンテナをUPするだけ。
version: '3' services: nginx-proxy: image: jwilder/nginx-proxy container_name: nginx-proxy ports: - 80:80 - 443:443 volumes: - /docker/nginx-proxy/certs:/etc/nginx/certs:ro - /docker/nginx-proxy/vhost:/etc/nginx/vhost.d - /docker/nginx-proxy/html:/usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro restart: always environment: TZ: Asia/Tokyo labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy" letsencrypt-nginx-proxy-companion: image: nginxproxy/acme-companion container_name: nginx-letsencrypt volumes: - /docker/nginx-proxy/certs:/etc/nginx/certs - /docker/nginx-proxy/vhost:/etc/nginx/vhost.d - /docker/nginx-proxy/html:/usr/share/nginx/html - /var/run/docker.sock:/var/run/docker.sock:ro restart: always depends_on: - nginx-proxy environment: TZ: Asia/Tokyo DEAULT_EMAIL: "xxxx@xxxx.xxx"
一番最後の行の「DEAULFT_EMAIL」に連絡先用メールアドレスを書いておくと、
転送先のコンテナにいちいちメールアドレスを書く必要がなくなるので、
ここに書いておくことを推奨。
リバースプロキシ用の"nginx-proxy"という名前のコンテナと、Let's EncryptでSSL証明書を発行してくれる"nginx-letsencrypt"というコンテナがそれぞれ起動し、
他のコンテナの稼働状況を確認し、自動的にSSL証明書発行とWeb転送を行なってくれる。
転送先のWebサーバ用コンテナ作成
次に転送先となるWebサーバのコンテナを用意する。
ここでは例として、「Portainer」のコンテナを立てることにする。
docker-compose.ymlで以下を作成。
version: "3" services: portainer: image: portainer/portainer-ce container_name: portainer ports: - 8000:8000 volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data restart: always environment: - TZ=Asia/Tokyo - VIRTUAL_HOST=xxxx.hogehoge.com - VIRTUAL_PORT=9000 - LETSENCRYPT_HOST=xxxx.hogehoge.com volumes: portainer_data: external: true networks: default: external: name: nginx-proxy_default
ポイントは以下。
「VIRTUAL_HOST」および「LETSENCRYPT_HOST」の値にアクセスしたいURLのFQDN名にすること。
「VIRTUAL_PORT」で本来Webアクセスするポート番号を指定すること。
「networks」で、リバースプロキシ用nginxコンテナと同じネットワークに所属させること。
"external"句で、外部コンテナのネットワークを利用することができる。
Portainerの場合は、「http://<IPアドレス>:9000」で本来はアクセスするので、
VIRTUAL_PORTは9000になる。
その他、ポート開放とDNSレコード更新
これでコンテナの準備は完了。
あとはサーバのポート開放。
80/tcpと443/tcpの2つを最低限開放。
80/tcpはLet's Encryptの証明書更新用に必要。
あとはVIRTUAL_HOSTで指定したFQDNに該当するDNSレコード(AレコードやCNAME等)を設定。
俺の場合、ポート開放はOCIのセキュリティリスト、
DNSレコードはAWSのRoute53なんだけど、割愛wwwwww
nginx.confの設定変更等は不要
DNSレコードが伝播して名前解決ができるようになると、
Webサーバにアクセスすることができる。
SSL証明書もご覧のとおり設定済み。
Let's Encrypt自体どうなの?っていうのもあるが、
オレオレ証明書よりかは遥かにマシだし、
それほどお金かけるほどでもないようなWebサービスを自前で運営したい時には便利なんじゃなかろうか?
商用利用するには、キチンとお金を出して、
AWSのACM+ELBの方が圧倒的に楽。
なので、この方法は手軽なんだけど、個人利用以外の用途で実用性は?という感じw
でも、個別にリバースプロキシの設定やら、SSL証明書の設定をチマチマ行うことを考えると圧倒的にこちらの方が楽だよね。
注意点
Let's Encryptの仕様上、SSL証明書発行には一定期間での上限が決められている。
んで、このコンテナは起動するたびに証明書を再作成する。
そのため、Let's Encryptのコンテナを何度も再起動していると、回数制限にひっかかってしまい証明書の発行ができなくなり、Webサーバにアクセスできなくなるので注意。
俺も設定する時にちょっと手間取ってしまい、何度もコンテナ再起動を繰り返していたら
制限にひっかかってしまった。
何日か経てば制限が解除されるのだけど、制限中はWebサーバダウンという扱いになってしまうので、
ブログ運営とかしてる環境では要注意!
コンテナにより、同一ホストで複数アプリをマイクロサービス化して動かすことが当たり前に。
Webアクセスする時にその都度、SSL設定する手間を省くことができるので、
便利な人はすげー便利なんじゃないかと。
ホストをk8s等でクラスタ化すればさらに完璧だな!w
0 件のコメント:
コメントを投稿