しばやん雑記

ASP.NET Core とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Web Apps に VuePress / Hugo を簡単にデプロイ出来るテンプレートを作った

深夜に Twitter で駄弁ってる時に「App Service に用意された仕組みを使えば、いい感じに静的サイトジェネレータを使ったサイトのビルドが行えるのでは?」と思ったので 1 日かけて作ってみました。

Firebase Hosting や Netlify と比べると App Service は設定項目が多すぎるので複雑です。今回のテンプレートは App Service ではありがちな「何でもできるよ?スクリプトを書けばね☆」みたいな状態なのを、ある程度は改善したいという思いがあります。

基本的なサイトを App Service でビルドして、そのままデプロイという流れまで動くようになっています。

実際にデプロイして試す場合は、以下の手順を参考にしてもらえれば良いです。

Azure Storage ではなく App Service を静的サイトのホスティングに使うメリットとしては、フロントに CDN を置くことなく HTTPS の設定が出来ることや、Twitter / Facebook / Google などのアカウントを使った認証を簡単に組み込めることです。

デメリットはやはり価格になってきますが、静的サイトの場合はかなりサイトを積み込めると思うので、そこで 1 サイトあたりのコストを圧縮は出来そうです。*1

Windows と IIS だとパフォーマンスが気になるかも知れないですが、静的なファイルの場合は簡単にキャッシュが効くのと、HTTP2 にも標準で対応しているので大きな差は出ないでしょう。

静的サイトジェネレータ向けに Web App を作成

ARM Template を工夫して、Web App 作成時に利用する静的サイトジェネレータとビルドに使うコマンド、そして生成されたサイトが含まれるディレクトリパスを入力するようにしました。

この辺りは Netlify を意識した設定項目にしています。そして静的サイトジェネレータは今のところ VuePress と Hugo のみ選べますが、拡張可能な実装なので増やすことも出来ます。

VuePress 向けの場合

VuePress 向けに作成する場合は Site Generator として VuePress を選択します。

Build Command と Publish Directory は環境によって異なりますが、一般的には npm run build.vuepress/dist であることが多いでしょう。

f:id:shiba-yan:20190703011611p:plain

入力が終わればデプロイします。これで VuePress 向けのビルドが行える Web App が完成です。

Hugo 向けの場合

Hugo の場合も VuePress と流れは同じなので、Site Generator は Hugo を選びます。

Build Command と Publish Directory は環境によって合わせる必要がありますが、こちらも一般的には hugopublic が多いでしょう。

f:id:shiba-yan:20190703011628p:plain

これでデプロイを行えば Hugo 向けの Web App が完成します。後はリポジトリを選ぶぐらいなので、App Service の設定はこれで実質終わりです。

ちなみにここで入力した Build Command と Publish Directory は App Settings に保存されているので、変更したい場合はここから上書きすれば問題ないです。

f:id:shiba-yan:20190703012904p:plain

出来るならこの辺りの設定画面も上手く隠したいのですが、そう頻繁に変えるものではないと思うので、とりあえずはこのままにしています。

Deployment Center からデプロイの設定

作成した Web App は既に VuePress / Hugo のビルド向けに最適化されているので、後はどのようにデプロイするかを設定するだけです。

デプロイに関する設定は Deployment Center からサクッと行えます。数多くのソースに対応していますが、基本的にはどれを選んでも問題なくビルドとデプロイは行えるはずです。

f:id:shiba-yan:20190703011711p:plain

注意点は Build Provider として App Service build service を選ぶ必要があることぐらいです。

f:id:shiba-yan:20190703011757p:plain

Azure Pipelines を選ぶと別にビルドパイプラインが作られるので、今回のテンプレートでは対応不可能です。

今回は VuePress を GitHub からデプロイ、Hugo をローカルの Git からデプロイというように、それぞれ別のソースで設定してみます。

GitHub からデプロイする場合

デプロイの設定はこれまでと全く変わらないので、ドキュメントがそのまま参考になります。

とは言っても Deployment Center の UI がシンプルなので、最初の画面から GitHub をクリックして、ポチポチと認証やデプロイしたいリポジトリとブランチを選んでいくぐらいで終わります。

f:id:shiba-yan:20190703011746p:plain

設定が完了すれば、自動的に最新のコミットがデプロイされます。初回は npm install が走るので少し遅いですが、それ以降のビルドは早くなります。

新しいコミットを GitHub にプッシュすれば、Web App 側も自動でビルドが走ります。

f:id:shiba-yan:20190703011849p:plain

Git の操作を行わなくても、Deployment Center の履歴から特定のコミットへの再デプロイも出来ます。

Local Git を使ってデプロイする場合

こちらもドキュメントがそのまま参考になるので、分からない部分は参照してください。

基本的には Local Git の設定後に表示された Git の URL をクローンして、その中でコミットを積み上げていくか、既存のリポジトリに新しく remote として追加するかのどちらかです。

ドキュメントにはユーザー名込みの以下のようなコマンドが載っていますが、Git Credential Manager が入っていればダイアログで認証情報を聞いてくれるので便利です。

git remote add azure https://<username>@<app-name>.scm.azurewebsites.net/<app-name>.git

既に Hugo の Quick Start に従ってリポジトリを用意していたので、新しく remote を追加しました。

追加して git push azure master を実行すればデプロイが行われます。ビルド中のログはクライアントに送信されるので、どのような処理が行われているか把握できます。

f:id:shiba-yan:20190703012245p:plain

Local Git の場合も Deployment Center から履歴の確認と、特定のコミットの再デプロイが行えます。

f:id:shiba-yan:20190703013654p:plain

Hugo に関しては使用するバージョンを App Settings に HUGO_VERSION キーを追加すると指定できます。今は現時点での最新バージョン 0.55.6 が使われるようになっています。

生成されたサイトを確認

VuePress と Hugo の両方ともデプロイが完了したので、ブラウザから確認しておきました。静的な HTML なので当然ですが、Windows の App Service でも問題なく動作しています。

f:id:shiba-yan:20190703013201p:plain

ARM Template を静的サイト向けに調整しているので、HTTP2 もデフォルトで有効化されています。

f:id:shiba-yan:20190703013536p:plain

404 ページはデフォルトでルートにある 404.html を設定しているので、存在しない URL にアクセスした場合でも正しく 404 ページが返って来ます。

これで一通り VuePress と Hugo を使ったサイトのデプロイまで終わりました。結局やったことは Web App のデプロイとリポジトリの設定だけで済みました。かなり簡単になったと思います。

おまけ:作成したサイトに認証を追加する

作成したサイトに認証を追加するのも簡単です。Azure Portal から App Service Authentication を有効にして、利用したい認証プロバイダを設定するだけで完了です。

f:id:shiba-yan:20190703015700p:plain

Basic 認証は用意されていないですが、大抵は用意されているプロバイダで事足りるかと思います。裏仕様っぽいですが OIDC に対応したプロバイダならカスタム追加も出来るようです。

*1:Shared がカスタムドメインでの HTTPS に対応して GA とかになれば強い