🌊
Azure App Service へのNode.jsアプリデプロイを大幅に改善した話
はじめに
仕事でNode.jsアプリを開発してましたが、デプロイに30 ~ 45分近くかかるようになり辛くなってきたので改善した話をまとめました。
改善後6分〜7分程度に短縮しました。
前提
今回はAzure App Service on Linuxをベースに試した内容を残しております。おそらく通常のApp Service (Windows版)も利用できるかと思います。
Web App for Containersは対象外です。
App Serviceとはなんぞや。という方はこちらをご覧ください。
要約
- zipでまとめよう
- 開発環境と、運用環境でパッケージの差分をなくすべく
npm ci(rm -rf node_modules && yarn install --frozen-lockfile)
を使いましょうね
詳細
App ServiceはGithubActionsとのデプロイ設定を行うと自動的に以下のようなワークフローを生成します。
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# 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
on:
push:
branches:
- stage
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: '16.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: 'main'
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: '< your app service name>'
slot-name: 'staging'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_B... }}
package: .
改善の詳細は以降に記述。
ビルド
npm install
をやめ、npm ci
にすることで、package-lock.jsonをもとにインストールするようにしました。意図しないパッケージのバージョンインストールを防ぐため。
またunit test終了後、再度productionのみ必要なパッケージをインストールすることで容量の軽量化を図っております。 npm ci --production
は実装の仕方やパッケージのインストールの仕方によっては不要にできる余地あり。
- name: npm install, build, and test
run: |
+ npm ci
+ npm run build --if-present
+ npm run test --if-present
+ npm ci --production
- npm install
- npm run build --if-present
- npm run test --if-present
zip化
zip化しました。軽量化。
+ - name: Zip all files for upload between jobs
+ run: zip --symlinks -r app.zip ./*
zipファイルを指定し、Artifactにアップロードするようにしました。
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: node-app
+ path: app.zip
- path: .
App Serviceへの展開はzipファイル指定することで、自動で展開するようにしました。
- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'app-flier-slack-app-stg'
slot-name: 'staging'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_B... }}
+ package: app.zip
- package: .
actionのVerup
以下のactioはデフォルトでv2になっているのでv3に上げる
- actions/checkout
- actions/setup-node
- actions/upload-artifact
- actions/download-artifact
コード全体はこちら
# 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
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js version
uses: actions/setup-node@v3
with:
node-version: '16.x'
- name: npm install, build, and test
run: |
npm ci
npm run build --if-present
npm run test --if-present
npm ci --production
- name: Zip all files for upload between jobs
run: zip --symlinks -r app.zip ./*
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v3
with:
name: node-app
path: app.zip
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'main'
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: 'app-flier-slack-app-stg'
slot-name: 'staging'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_B... }}
package: app.zip
最後に
cacheを使うなど、まだまだ改善の余地はある。
見つけ次第、updateしていきます。
Discussion