Azure WebAppsにGitHub Actions経由でアプリケーションのデプロイをするとデフォルトで作成されるymlファイルの設定的にめちゃめちゃデプロイが遅いので、設定を見直してみました。
結果からいうと 25分から1分代にまで時間が短縮できました。(デフォルトが掛かりすぎ疑惑あります)
Azureなど関係なく高速化できそうなポイントがあると思います。
過去にもGitHub Actionsの設定見直しをしていましたが、今回も久々にAzure WebAppsにデプロイしてトライしたあたりのメモを書いていきます。
前提としてNode.jsでのDiscord BotのプログラムをAzure WebAppsにコードデプロイをしています。
Azure側から発行されるデフォルトの設定でデプロイ(25分)
物によると思いますが、デプロイしようとしたDiscord Botのアプリケーションはとりあえずそのままデプロイすると25分かかりました。結構かかりますね...
デフォルトだとnpm run test --if-present
のあたりでコケるのでコメントアウトだけして動かしています。
初期のYAMLファイル
Azure側から自動生成されるやつです。
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions
name: Build and deploy Node.js app to Azure Web App - prototoout-bot
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js version
uses: actions/setup-node@v1
with:
node-version: '18.x'
- name: npm install, build, and test
run: |
npm install
# npm run build --if-present
# npm run test --if-present
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: node-app
path: .
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v2
with:
name: node-app
- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'prototoout-bot'
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_xxxxxxxxxxxxxxxxxxxxxxxxxx }}
package: .
zip化する(25分=>8分に)
デフォルトのままだとnode_modulesなどに含まれる多数のファイルをデプロイしますが、ファイル数が多いことによって時間がかかっている模様でした。
@horihiroさんの記事が参考になりました。
release.zipというファイルにカレントディレクトリ内のフォルダをまとめつつ、
run: zip release.zip ./* -qr
release.zipの1ファイルだけをアップロードする感じです。
path: release.zip
8分19秒、だいぶ早くなりました。
pnpmとキャッシュを試す(8分=>6分)
pnpmが速いという噂があるのでキャッシュ込みで更に試してみました。
pnpmがどうというよりもキャッシュさせたところが効いていた気がします。
確かこの時のキャッシュされたキャッシュサイズが25MBほどでした。
ただ、たぶん設定はあると思いますが、pnpmの仕様上なのか、グローバルにモジュールがインストールされるような仕組みの模様で、zip化してデプロイするときにうまくファイルが乗らずデプロイ先のWebAppsでアプリケーションが上手く起動できない事象が発生していました。
一応記録的に記事には残してますが、pnpmは最終版では採用していません。
yarnとキャッシュを試す(6分=>4分)
yarnはどうなのだろうとyarnとキャッシュを入れて試してみました。4分代にまで短くなっています。
確かキャッシュサイズは30~40MBほどになってました。
参考: https://blog.lacolaco.net/2021/06/github-actions-yarn-cache/
結構早くなってきてますね。
利用するActionのバージョンを上げる(4分=>3分)
利用するActionがAzureのデフォルトのままだと2系になっていますが、3系に直しましょうといったアラートがちょくちょくでていました。
actions/setup-node@v3
やactions/download-artifact@v3
などActionのバージョンを2から3に指定しなおすことで若干早くなった印象です。
現時点で最新にしてアラートがなくなったYAMLファイルはこちらです。
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions
name: Build and deploy Node.js app to Azure Web App - prototoout-bot
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Code Checkout
uses: actions/checkout@v3
- name: Set up Node.js version
uses: actions/setup-node@v3
with:
node-version: '18.x'
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: npm install, build, and test
run: |
yarn install
- name: Zip artifact for deployment
run: zip release.zip ./* -qr # 除外したいディレクトリがあるなら -x オプションで指定
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v3
with:
name: node-app
path: release.zip
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v3
with:
name: node-app
- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'prototoout-bot'
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_xxxxxxxxxxxxxxxxxxxx }}
package: release.zip
アプリケーション内のライブラリの更新と整理(3分=>1~2分に)
これが原因かは分からないですが、Discord.jsをv13からv14に上げた辺りでデプロイの速度がまた上がっていました。
他のライブラリも更新したタイミングだったのでイマイチ原因不明感はありますが、効率化されてる部分もあるのかもしれません。
まとめ
zipは偉大ですね。
キャッシュはもっと上手く使える気がします。