ASP.NET Core MVCでブログを作ってCI構築してそこからデプロイするようにした

 .NET Core 2.0が出たので、このブログのエンジンを再構築しなおした。ついでにDockerコンテナで運用するようにし、ホスティングもコンテナでやるHyper.shに移る。
デプロイは、
開発→Github→AzureWebApp
だったのが、
開発→Github→TravisCI→Hyper.sh
になり、自動テストを経ることになった。masterへのコミットのみ、Hyper.shへのデプロイが実行されるようにしてある。あとはCIでOAuthつけたらひと段落。
https://github.com/hMatoba/tetsujin


https://blog.hmatoba.net
comment: 0

継続的デプロイと継続認証のコンテナ

 DockerコンテナでLet's Encryptと継続的デプロイをなにも考えずに組み合わせたら大失敗だった。Let's Encryptには証明書取得数の上限があった。
https://absurd.azurewebsites.net/Article/118

 上記の問題を、証明書を外部ボリュームに入れて運用するDockerイメージを作ることで解決した。
https://github.com/hMatoba/cdcc

 下記はコンテナホスティングサービスHyper.sh上で、このDockerイメージを作って運用するときのdocker-compose。証明書を自動で取りに行って、WebアプリをHTTPS運用するコンテナとしてよしなにやってくれる。
docker-compose.yml

version: '2'

services:
cdcc:
image: matoba/cdcc
ports:
- '80:80'
- '443:443'
fip: 199.245.56.122
size: s4
links:
- webapp:webapp1
volumes:
- cdcc:/etc/letsencrypt
environment:
DOMAIN: 'example.com'
E_MAIL: 'foobar@example.com'
LINK_NAME: 'webapp1'
webapp:
image: some_webapp
ports:
- '80:80'
comment: 0

Let's Encryptで証明書を取ってみた(DockerのNginXコンテナ(Alpine)から)

 タイトルの通り、Let's Encryptで証明書を取ってみた。DockerのNginXコンテナ(Alpine)から。メモ。ちなみにHyper.shでコンテナのホスティングは行っている。なのでコンテナを動かすコマンド体系はHyper.sh準拠。ほぼDockerコマンドのまんま。

 まずコンテナを用意。
hyper run -d --name foo -p 80:80 -p 443:443 nginx:alpine


 IPをつける。DNS設定はしてあるものとする。
hyper fip attach xxx.xxx.xxx.xxx foo


 NginXコンテナが動いていて、そこへDNS設定してあるIPをつけたのだからアクセスできるはず。URLを入れてアクセスできるか確認しておく。



 コンテナへ入る。
hyper exec -it foo /bin/sh


 認証を実行してくれるライブラリを入れる。
apk update

apk add certbot


 下記でヘルプが表示される。
certbot -h


 すでにこのコンテナではNginXが動いている。デフォルトの設定で。だからcertbotには、NginXを使った認証コマンドを実行してもらう。
certbot certonly --webroot -w /usr/share/nginx/html -d hmatoba.net

これでインストラクションに従って入力していくだけ。成功すれば発行されたというメッセージとともにファイルが出力される。


 自動化のために、インストラクションで進める形はやめて、オプションを与えていかなければならない。しかしまあ証明書は取れた。めでたしめでたし。
comment: 0

Hyper.shでSSL接続するアプリの継続的デプロイ(まだ決定打なしのイマイチな方法)

 Dockerコンテナでアプリを運用したい場合、Hyper.shがイカす。そのHyper.shで、Let's encryptで取得する証明書を使ってHTTPSで接続できるようにしてみる。

Serviceを使う
→コンテナ立ち上げコマンドで証明書を引数として渡している。Let's encryptは証明書の有効期間が短いから自動更新を繰り返していきたいんだけど、そのたびにコンテナを立ち上げ直さなきゃならない?それをクリアできるならば一番いい方法

・アプリコンテナにリバースプロキシを入れてごにょごにょ
→アプリコンテナがちょいややこしくなるのと後述する理由でナシ

・アプリコンテナの外にリバースプロキシコンテナを用意して接続
https-portalという、超簡単にLet's encryptの証明書でSSLを使えるようにしてくれるコンテナがある。これを使って今回はやってみるが、結果は問題が残った。

 https-portalのGithubページのサンプルをちょっといじったdocker-compose.ymlを書く。
docker-compose.yml

version: '2'

services:
https-portal:
image: steveltn/https-portal:1
ports:
- '80:80'
- '443:443'
environment:
DOMAINS: 'example.com -> http://dncindocker'
STAGE: 'production'
FORCE_RENEW: 'true'
fip: xxx.xxx.xxx.xxx
dncindocker:
image: matoba/dncindocker:latest

 こいつをHyper.shへ。
hyper compose -up d -p foo

これで一分ほど待てばアプリのデプロイが完了するだろう。このコマンドに加えて下記のコマンドでプロジェクト消去コマンドがあれば、デプロイを容易にサイクル化できる。
hyper compose rm -v -p foo


 で、この方法はデプロイするたびにhttps-portalコンテナが証明書を取りに行く。これが問題となる。じっさいデプロイを何度も試しているうちに遭遇したのが、証明書の期間あたりの取得上限。変更がなければ週に20回までのようだ。これに達すれば証明書の発行はいったんストップするので、https-portalコンテナが正常な動作をしなくなる。そういうわけで、https-portalコンテナをデプロイの度に動かし直すのはよくない。コンテナのデプロイを分けなければならない。そうしたらそうしたで、デプロイの度にどうやってhttps-portalコンテナからアプリコンテナへの接続をやるかという課題が生まれる。
 そういうわけでLet's encrypt + 継続的デプロイのプロセスの確立に失敗した。

解決のために取るべき方法
・Serviceで証明書の自動更新と継続的デプロイができるか調査
・リバースプロキシコンテナとアプリコンテナをComposeで管理しない。リバースプロキシコンテナは動かしっぱなし、アプリコンテナだけを更新。走りっぱなしのリバースプロキシコンテナからアプリコンテナへの接続手段を得る。
comment: 0