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

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

TravisCIからHyper.shへDockerコンテナなアプリを継続的デプロイ

 Dockerコンテナなアプリをホビー用途でデプロイするならHyper.shがとてもイカしてる。そんなHyper.shとTravisCIを掛け合わせて継続的デプロイを組んでみる。

 このブログで、TravisCIから、テストにとおったアプリのDockerイメージを、継続的にDocker hubへプッシュしていくまではやっている。
.NET CoreのDockerコンテナに入ったWebアプリをTravisCIでCI
 今回はDocker hubへのプッシュ後に、Hyper.shのCLIツールをそのままTravisCIで使ってDockerコンテナを走らせるまで。

 まずHyper.shでアクセストークンとキートークンを発行し、TravisCIで環境変数にセット。




 続いて.travis.ymlにHyper.shのCLIツールでの処理(コンテナ立ち上げ)を追加。
.travis.yml

after_success:
- docker tag matoba/dncindocker:ci matoba/dncindocker:latest
- docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}"
- docker push matoba/dncindocker:latest
- wget https://hyper-install.s3.amazonaws.com/hyper-linux-x86_64.tar.gz
- tar xzf hyper-linux-x86_64.tar.gz
- ./hyper --help
- ./hyper config --accesskey ${HYPER_ACCESS} --secretkey ${HYPER_KEY}
- ./hyper run -d -p 80:80 --name mersault matoba/dncindocker:latest



 上記までで設定はOK。TravisCIでのテストを走らせる前、Hyper.shではコンテナやイメージはまだゼロ。



 TravisCIでのテストが通ったあとに見るとコンテナやイメージにカウントが増えている



 しっかりコンテナが動いている。



 IPを当ててブラウザでアクセスしてみる。



 管理コンソールを見ていると環境変数を入れるフォームはなさそう。そうなると環境変数を与えられるタイミングはコンテナを起動させるタイミングである。アプリで使われる環境変数はTravisCIに入れて運用していくことになるんかな。
comment: 0