キーワードを詰め込んだら長いタイトルになりました。
静的サイトのホスティング方法
Azure で静的サイトをホスティングするにはいくつか方法があります。
- Azure Web App
- Azure CDN + Blob Storage
- Azure Function Proxy + Blob Storage
大まかに3つあります。
Azure Web App
オーソドックスな方法です。
カスタムドメインを適用するには Shared プラン以上が必要なので、日本リージョンで運用するには大体月1000円以上かかります。(公式:App Service 料金)
このパターンについてはギョームで使っているのでそのうち別媒体で書きます。
Azure CDN + Blob Storage
費用はアクセスが少なければ月数十円で済むでしょう。
なぜ Blob Storage の手前に CDN を挟む必要があるかというと、以下の記事が大変よくまとまっています。
Blob Storage のツラみを CDN でどうにかしてやろうということです。
CDN が SSL 証明書の面倒を見てくれるということで大変ありがたいです。
スケーラビリティも言うことなしでしょう。
しかし CDN で URL Rewrite するルールの適用が4時間以上かかるということで、待つのがかったるいです。
この記事を書いている間は絶賛待機中なのですが、待っている間に Function で試したところ動いたのでもういいかというところが今ココです。
Azure Function Proxy + Blob Storage
こちらも費用はアクセス次第ですが数十円から運用可能です。
Blob Storage で管理しやすいように管理するコンテンツの URL を Function Proxy でいい感じに整えるという役割分担です。
カスタムドメインや SSL 終端は Azure Function が担当します。
なお、今回の例では SSL証明書 は Let's Encrypt を使っているので無料です。
実現方法
ということで本題。
完成品
まずは成果物です。
(2018/7/8 追記: こちらの記事で Blob の Static Website によるホスティングに変更済み)
コンテンツは何でもいいですが、Jekyll で作成したレジュメっぽいものを置いています。
GitHub - kheiakiyama/kheiakiyama.github.com at 12dc107f19cdea04a73fd72ec877c2e1f57acf13
余談ですが Octopress はどこに行ったんでしょうね。
GitHub から Blob Storage へのデプロイ
Web App には GitHub からの継続的デプロイ方法が提供されていますが、Blob ではもちろんありません。
そこで Travis CI を使っています。
デバッグ用コード多めです。
(上のリンクを開いた前提で)やっていることをざっくり書くと以下のとおりです。
- Jekyll のビルド
- .NET Core のインストール
- AzCopy のインストール
- AzCopy で Jekyll の成果物を Blob にコピー
Travis CI の権限周りがよくわからなかったので .NET Core のインストールはコピーしてきて手元で動かすだけという雑な作りになっています。
また、AzCopy で set-content-type
しないと Blob 側の配信がすべて application/octet-stream
になるという悲しい現象が起きるため、拡張子ごとにコピーするというイケてないコードになっています。
Function でヘッダーを上書きするのもありますが、Blob の時点で動作確認できる方が原因切り分けの面で有利なので Blob で実現しています。
コンテンツの一部ファイルが削除された場合など考慮することが他にもありますが、まずはこれで。
Azure Function の実装
proxies.json
は以下のとおりです。
{ "$schema": "http://json.schemastore.org/proxies", "proxies": { "blob-route": { "matchCondition": { "route": "/" }, "backendUri": "http://{your_storage}.blob.core.windows.net/{container}/index.html" }, "blob-index": { "matchCondition": { "route": "/index.html" }, "backendUri": "http://{your_storage}.blob.core.windows.net/{container}/index.html" }, "blob-asserts": { "matchCondition": { "route": "/assets/{*file}" }, "backendUri": "https://{your_storage}.blob.core.windows.net/{container}/assets/{file}" }, "letsencrypt": { "matchCondition": { "route": "/.well-known/acme-challenge/{*rest}" }, "backendUri": "https://%WEBSITE_HOSTNAME%/api/letsencrypt/{rest}" } } }
Blob Storage から取得したいファイルを Proxy する以外では Let's Encrypt の承認プロセスのための API を Proxy しています。
このあたりは 公式の Wiki に書いてある通りに書いただけです。
Proxy 以外にも api/letsencrypt/{rest}
の部分を実装する必要があります。
上述の公式の Wiki を参考に C# か NodeJS の内容をコピペしましょう。
余談ですが Azure ポータルと App Service Editor を両方開きながら相互に読み書きしたところ proxies.json
が消えるハプニングが起きました。ローカルに適宜バックアップしながら作業を進めるのが無難です。
Azure Function でカスタムドメインと SSL の設定
Let's Encrypt の導入については Azure Function でも Web App でも上記の Proxy 部分以外に差はありません。
How to install · sjkp/letsencrypt-siteextension Wiki · GitHub
公式の手順を参考に粛々と作業を進めましょう。
英語がニガテな方は以下サイトを参考にするとよさそうです。
Azure Web Apps に Let's Encrypt を使って簡単に SSL を導入する - えむにわリソース
無事完了すると SSL 証明書が割り当てられ、カスタムドメインと SSL バインディングされた状態になります。
https://{your_site}.scm.azurewebsites.net/.well-known/acme-challenge/{*rest}
のリダイレクトでエラーになった場合は Function Proxy の実装が上手くいっていないと思われます。
一つずつ見直しましょう。
参考にした記事
最後に
Proxy は書き換え直後にすぐ動くので使っていて気持ちいいです。
最初に上げた通り、実現方法のパターンはいくつかありますが、要件に合わせて適切に使っていきたいものです。
CDN をいじるつもりが気付いたら Function Proxy でホスティングしていた
— kheiakiyama (@kheiakiyama) 2018年2月12日
- 作者: 久森達郎、真壁徹、大田昌幸、藤本浩介、佐藤直生、安納順一、松崎剛、高添修,日本マイクロソフト株式会社
- 出版社/メーカー: 日経BP社
- 発売日: 2017/11/17
- メディア: 単行本
- この商品を含むブログ (1件) を見る