これまで Grav を使って shibayan.jp にペライチのコンテンツを配置していたのですが、メンテナンスが面倒だったりパフォーマンスに問題があったので移行を考えていました。
そして今日もアップデートが失敗して Composer からやり直しになった結果、三宅さんに教えてもらった VuePress への移行を決意しました。
vuepress まだ1.0になったばかりですが
— k-miyake (@kazuyukimiyake) 2019年7月1日
さっと公式サイトとドキュメントを眺めた感じでは、Markdown で書いてしまえばビルド時に静的な html やアセットが生成されるようでした。
それを App Service にデプロイすれば快適に動作すると確信したので、一気に CI / CD 含めて移行しました。
VuePress で簡単なサイトを作る
この辺りはドキュメントを読みながら進めましたが、CI のことを考えて VuePress はグローバルにインストールしないようにしました。
適当に package.json
を用意して、簡単に開発とビルドが行えるようにします。
{ "name": "shibayan.jp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "vuepress dev src", "build": "vuepress build src" }, "author": "", "license": "ISC", "dependencies": { "vuepress": "^1.0.2" } }
Node.js 力が低いのでこれであってるのか分からないですが、問題なく動いてはいます。
最初はリポジトリのルートにそのまま Markdown ファイルを置いてましたが、分かりにくくなったので src という名前でディレクトリを切って、その中に VuePress 用のファイルを入れるようにしました。
VuePress の設定が出来れば、後は Grav から Markdown を殆どそのまま移行しました。ほぼペライチのサイトだったので、ページ自体は一瞬で移行出来ました。
元々のサイトでは Web.config を使って、カスタムドメインへのリダイレクト強制や HSTS などの設定を行っていたので、.vuepress/public
に Web.config を置いてデプロイされるようにしました。
Azure Pipelines で VuePress をビルドする
サイト自体は一瞬で完成したので、次は Azure Pipelines を使ってビルドとデプロイのパイプラインを構築します。これまでは Classic Editor を使って書いてきましたが、今回は YAML を使ってみました。
UI に従ってビルドするリポジトリを選ぶと、ファイルをスキャンして推奨されるテンプレートを表示してくれます。今回は通常の Node.js テンプレートを使いました。
Node.js のテンプレートを選ぶと npm install
と npm run build
だけ行われる定義が生成されます。テンプレートを選ぶだけで、必要なタスクの半分は完成しています。
Azure Pipelines の YAML エディタが結構使いやすかったのと、GitHub とのインテグレーションがかなり強力だったので結構いけてました。
YAML を編集し、保存する際には同じブランチにコミットを作るか、それとも別ブランチに作るか聞いてくれます。GitHub のエディタと近い挙動です。
Pull Request をまだ作っていなくても、保存したコミットを Queue に入れてビルドする機能もあるので、ビルド定義を書いている時のテストが行いやすかったです。
最終的には以下のような YAML を書いて VuePress のビルドを行います。
# Node.js # Build a general Node.js project with npm. # Add steps that analyze code, save build artifacts, deploy, and more: # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript trigger: - master pool: vmImage: 'ubuntu-latest' steps: - task: NodeTool@0 inputs: versionSpec: '10.x' displayName: 'Install Node.js' - script: | npm install npm run build -- --dest dist displayName: 'npm install and build' - task: ArchiveFiles@2 inputs: rootFolderOrFile: '$(Build.SourcesDirectory)/dist' includeRootFolder: false archiveType: 'zip' archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildNumber).zip' replaceExistingArchive: true displayName: 'Archive artifact' - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)' ArtifactName: 'drop' publishLocation: 'Container' displayName: 'Publish artifact'
VuePress のビルド結果を zip で圧縮して、Azure Pipelines の Artifact として保存するだけの簡単な定義です。
ビルドは 1 分以内で大体終わっていました。ビルド結果は保存されているので、後は Release パイプラインで App Service にデプロイするだけです。
App Service に Run From Package としてデプロイ
VuePress でのビルド結果は静的なファイルなので Run From Package を使ってデプロイします。
実行時に処理する部分がないので Azure Storage の Static website hosting でも良いですが、カスタムドメインと HTTPS のことを考えると App Service の方が楽です。
Release パイプラインは例によって Azure Web App タスクを使ってデプロイします。
Deployment options で Run From Package を選ぶのを忘れないように気を付けましょう。
後は Continuous deployment trigger の設定をすれば、ビルド完了後にデプロイが行われます。
実際にコミットすると、自動的にデプロイまで実行されることが確認できます。
もちろん App Service にアクセスすると、VuePress で作成したサイトが表示されます。静的なサイトかつ Run From Package で動作しているので、App Service の弱点である I/O 周りを改善できます。
まだ全然 VuePress の機能を使えていないですが、CI 周りを組んでしまえば更新が非常に楽になるので、これから時間のある時を見つけて作業していく予定です。
あともう少し Azure Pipelines の YAML 周りを深堀したいとも思ってます。