Azure / webapps-deploy

Enable GitHub developers to deploy to Azure WebApps using GitHub Actions
MIT License
260 stars 185 forks source link

Deploy very slow using NodeJs #229

Open kimmy-wang opened 2 years ago

kimmy-wang commented 2 years ago

14 minutes to build, 25 minutes to deploy and it's not over.

github-actions[bot] commented 2 years ago

This issue is idle because it has been open for 14 days with no activity.

rabollin commented 1 year ago

Triaged and added to backlog.

dennisameling commented 1 year ago

I was also running into this. Deployments were taking more than 30 mins to complete. The reason is that Kudu takes the ZIP it receives, then extracts it, and copies all files into /home/site/wwwroot. Since Node's node_modules folder often contains tens of thousands of files, this causes things to be super slow.

Command: "/home/site/deployments/tools/deploy.sh"
Handling Basic Web Site deployment.
Kudu sync from: '/tmp/zipdeploy/extracted' to: '/home/site/wwwroot'
Copying file: '.env'
Copying file: '.env.test'
Copying file: '.eslintrc.js'
Copying file: '.funcignore'
Copying file: '.gitattributes'
Copying file: '.gitignore'
....
Omitting next output lines...
Processed 1162 files...
Processed 2332 files...
....

Luckily there's a setting that allows you to start the app directly from the ZIP package rather than all this unzipping and copying: WEBSITE_RUN_FROM_PACKAGE="1". You can set it by doing:

az webapp config appsettings set --resource-group <group-name> --name <app-name> --settings WEBSITE_RUN_FROM_PACKAGE="1"

After changing this setting, it took less than a minute for my app to be deployed!! 🚀

https://docs.microsoft.com/en-us/azure/app-service/deploy-run-package#enable-running-from-package

sven5 commented 1 year ago

@dennisameling You should mention that WEBSITE_RUN_FROM_PACKAGE="1" only works for App Services that runs on a Windows plan. This is no solution for Linux plans, is it?

oshihirii commented 1 year ago

I am new to Azure web apps, and when I push to GitHub it takes 30 minutes for the 'workflow' to complete.

The workflow file was created automatically by Azure when creating the Web App a few weeks ago.

I updated the actions to use v3 to get rid of these warnings:

Warning 01:  
build  
Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/checkout@v2, actions/setup-node@v1, actions/upload-artifact@v2

Warning 02:  
build
There are over 10,000 files in this artifact, consider creating an archive before upload to improve the upload performance.

Warning 03:  
deploy
Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/download-artifact@v2

Warning 04:  
deploy
The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

Below is the contents of my workflow file:

# 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 - <my-app-name>

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: '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@v3
        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@v3
        with:
          name: node-app

      - name: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: '<my-app-name>'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_******** }}
          package: .

The only remaining warning is this one:

build  
There are over 10,000 files in this artifact, consider creating an archive before upload to improve the upload performance.
shpraka commented 1 year ago

@kw214 is it still happening? Are you using workflow file similar to https://github.com/Azure/actions-workflow-samples/blob/master/AppService/node.js-webapp-on-azure.yml?

shpraka commented 1 year ago

@oshihirii could you try using https://github.com/Azure/actions-workflow-samples/blob/master/AppService/node.js-webapp-on-azure.yml as a reference for your workflow file and see if it works?

Also see if setting the appsetting WEBSITE_RUN_FROM_PACKAGE="1" helps.

tommcclean commented 1 year ago

Would be great if this could be fixed, I have a few apps I gave up on Azure with over the years as they all build on netlify in < 1 minute. Just this evening revisited to see if improved and it isn't yet.

oshihirii commented 1 year ago

@dennisameling You should mention that WEBSITE_RUN_FROM_PACKAGE="1" only works for App Services that runs on a Windows plan. This is no solution for Linux plans, is it?

@shpraka

I am new to workflow files, so am nervous to try the file you suggested because it is so different to my existing file (pasted in my comment above).

Also, there was a question above about whether WEBSITE_RUN_FROM_PACKAGE="1" works in a Linux environment or not.

My environment is the test Linux one.

shpraka commented 1 year ago

@oshihirii WEBSITE_RUN_FROM_PACKAGE="1" should work for Linux environment as well. Let me know if it doesn't work.

hharb3 commented 1 year ago

in upload artifacts include only build directory

-name: Upload artifact for deployment job uses: actions/upload-artifact@v2 with: name: node-app path: build/

oshihirii commented 1 year ago

@hharb3 can you please add an explanation of what the code you posted will achieve and how/why?

oshihirii commented 1 year ago

@shpraka

Using the file you suggested as a foundation:

https://github.com/Azure/actions-workflow-samples/blob/master/AppService/node.js-webapp-on-azure.yml

I modified it so that it had some values that were in my original file.

(My original file was automatically generated by Azure and added into my GitHub repo).

The modified code I used is at the end of this post for reference.

I also followed your suggestion to enable:

WEBSITE_RUN_FROM_PACKAGE="1"

To do that, I had to download and install Azure CLI on my Windows machine and run the following in cmd:

az login  // to login, it opens a browser window to login  

az webapp config appsettings set --resource-group <my-resource-group-name> --name <my-app-name> --settings WEBSITE_RUN_FROM_PACKAGE="1"

As a result of these changes, the build and deploy time has been reduced from over 30 minutes to 1 minute 4 seconds.

For reference, my new workflow file code is below.

I've added comments to distinguish changes I made between my original and the suggested file.

name: Deploy Node.js to Azure Web App

# this was '[push]' in the suggested file  
on:
  push:
    branches:
      - main

# CONFIGURATION
# For help, go to https://github.com/Azure/Actions
#
# 1. Set up the following secrets in your repository:
#   AZURE_WEBAPP_PUBLISH_PROFILE  
#
# 2. Change these variables for your configuration:
env:
  AZURE_WEBAPP_NAME: <my-app-name>    # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: '18.x'                # set this to the node version to use

jobs:
  build-and-deploy:
    name: Build and Deploy
    runs-on: ubuntu-latest
    environment: production # this was 'dev' in the suggested file  
    steps:
    - uses: actions/checkout@v3 # this was '@master' in the suggested file 
    - name: Use Node.js ${{ env.NODE_VERSION }} # this was 'Set up Node.js version' in my original file 
      uses: actions/setup-node@v3 # this was 'v1' in the suggested file 
      with:
        node-version: ${{ env.NODE_VERSION }}
    - name: npm install, build, and test
      # this section was different in my original file  
      run: |
        # Build and test the project, then
        # deploy to Azure Web App.
        npm prune --production
        npm install
        npm run build --if-present
        # npm run test --if-present
    - name: 'Deploy to Azure WebApp'
      uses: azure/webapps-deploy@v2
      with: 
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        slot-name: 'Production'  # <-- this property wasn't in suggested file  
        # publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}   <--- in suggested file  
        publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_**** }} # taken from original file
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

  # For more information on GitHub Actions for Azure, refer to https://github.com/Azure/Actions
  # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples

Caveat/Disclaimer: Because I am not familiar with how these workflow files actually work, I'm not sure if it caused any undesired consequences that I am not aware of.

shpraka commented 1 year ago

@oshihirii Great to see that you were able to improve the deployment time. If there is no further issue I will go ahead and close this one.

dennisameling commented 1 year ago

@dennisameling You should mention that WEBSITE_RUN_FROM_PACKAGE="1" only works for App Services that runs on a Windows plan. This is no solution for Linux plans, is it?

Just wanted to confirm here that I've been using this on Linux for a few months and it works just fine 👍🏼

@oshihirii Great to see that you were able to improve the deployment time. If there is no further issue I will go ahead and close this one.

@shpraka before closing this issue, could we at least add something about this to the README of this Action? The default experience is absolutely tedious as it takes 30+ mins to deploy something without this setting. Thanks!

https://docs.microsoft.com/en-us/azure/app-service/deploy-run-package#enable-running-from-package

oshihirii commented 1 year ago

Can I also suggest that the default yaml file that is created by Azure for node web applications is updated to include:

shpraka commented 1 year ago

@dennisameling @oshihirii thanks for your feedback. We will update the readme on the repo.

We have also noted the feedback on yaml for Azure and will work on it.

shpraka commented 1 year ago

Updated the readme as part #287

dennisameling commented 1 year ago

Thanks @shpraka! Appreciate it!

tefkah commented 1 year ago

Zip deploy with WEBSITE_RUN_FROM_PACKAGE = 1 is not a universal solution, some webapps modify the filesystem while running (for a basic cache or something), but using zip deploy makes all the files in wwwroot readonly.

yavuzakyuz commented 1 year ago

@sven5 it does work with both Debian and Ubuntu machines (16.04, Bullseye 11.0)

KuNman commented 1 year ago

Screenshot 2023-04-28 at 10 44 56 Guys working in Microsoft, is it a joke?

NoCopy commented 1 year ago

@dennisameling You should never, ever, deploy your node modules folder to production. Any given package can open up a security vulnerability even if you are not using that function in your code. Use a build solution like Webpack or similar.

KuNman commented 1 year ago

How app can work without node_modules? @NoCopy

NoCopy commented 1 year ago

@KuNman Well, as I stated above you should use a build solution such as webpack - preferably with Tree shaking (which webpack supports): https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking

The compiled file will only contain the functions you need to run for your application. Adding node modules as a whole and not properly securing it can lead to serious security problems.

sgollapudi77 commented 1 year ago

Closing this issue as there's a setting that allows you to start the app directly from the ZIP package rather than all this unzipping and copying: WEBSITE_RUN_FROM_PACKAGE="1". You can set it by following this.

surenderssm commented 11 months ago

Reopening this as WEBSITE_RUN_FROM_PACKAGE="1" will not work for the apps which takes a dependency on /home/site/wwwroot for write operations.

amhed-dtg commented 10 months ago

Same problem for me. If I set WEBSITE_RUN_FROM_PACKAGE="1" the app compiles + builds fast but the the site gets served as static instead of as a node app.

If I remove the app setting then everything works, but it takes 30 mins to compile + package + upload form the github actions

# 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 + Deploy

on:
  push:
    branches:
      - master
  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: "18.x"
          cache: "yarn"

      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT

      - name: yarn install, build, and test
        run: |
          yarn install
          yarn run build

      - name: Building web app
        uses: azure/appservice-build@v3

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v3
        with:
          name: node-app
          path: |
            .
            !./src
            !./github
            !./node_modules

      # - name: unit tests
      #   run: yarn run test

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: "Production"
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: "Deploy to Azure Web App"
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: "my-app-name"
          slot-name: "Production"
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
Casperjuel commented 8 months ago

@sgollapudi77 Any updates on this issue? 👀

amhed-dtg commented 8 months ago

We ended up dockerizing everything

sgollapudi77 commented 8 months ago

Hey @Casperjuel, @amhed-dtg, @NoCopy, @KuNman, @hharb3, @kimmy-wang, @dennisameling, @oshihirii, @tommcclean, @AmrutaKawade, @0gust1, @rachael-ross, @sfabriece, @sabeeshvk, @mcthick, @mweel1, @zhughes3, @jsmircic, @kizylirio, @Blakerunner, @bibekgaihre, @abacaj

StephanBis commented 7 months ago

@sgollapudi77 yes, zipping and unzipping speeds up the step between build and deploy stages. But this doesn't fix the fact that the actual deploy is just painstakingly slow. Running from package is no option for us. Is there nothing else that can be done here?

jermbo002 commented 7 months ago

@sgollapudi77 as @StephanBis said the "Deploy to Azure Web App" step takes a significant amount of time. For most of our projects this step still takes over 15 minutes to complete. Some help for this step would be greatly appreciated.

davidwandar commented 5 months ago

I dont understand how this can not get solved properly. If you anyone in the team would create a project with a few packages and create an azure app with deploy through github actions, the deploy-step in the default yaml-workflow would take significant time, due to how it is set up. Either microsoft/github thinks this is fine, or they dont understand the problem, its been 100s of comments over years. Using any other service is at least 10x faster.

efischler commented 4 months ago

@sgollapudi77 Can we get an update on this thread? It is still very much an issue, deploy to azure web app taking an insane amount of time.

We have tried using run from webpackage = 1 but that appears to set wwwroot into a read-only state, and thus makes our app unreadable from the zip. So then falling back to the original method of unzipping / deploying the artifact takes 1h 48m, using azure/webapps-deploy@v3.

amsimon commented 4 months ago

@sgollapudi77

The amount of money Microsoft is missing out on because of this issue must be absolutely incredible.

I have avoided deploying to Azure many times over the last few years because for some unexplained reason, Microsoft engineers and project managers can't figure out how to make deploying to Azure actually functional while dozens of other companies can do it just fine.

mweel1 commented 4 months ago

Because DotNet?Sent from my iPhoneOn Mar 13, 2024, at 2:51 PM, amsimon @.***> wrote: @sgollapudi77 The amount of money Microsoft is missing out on because of this issue must be absolutely incredible. I have avoided deploying to Azure many times over the last few years because for some unexplained reason, Microsoft engineers and project managers can't figure out how to make deploying to Azure actually functional while dozens of other companies can do it just fine.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

Yerden01 commented 4 months ago

Hello, if someone have troubles like I had there is a way without using zip and unzip

name: Build and deploy Node.js app to Azure Web App

env:
  AZURE_WEBAPP_PACKAGE_PATH: './build'

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        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: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'app-name'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_YOUR_SECRET }}
          package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

This way took only 10 minutes, 5 minutes to build and other 5 to deploy.

Also you have to add startup command in your configuration: pm2 serve /home/site/wwwroot/ --no-daemon --spa

image

mweel1 commented 4 months ago

The real problem for me is that we send node modules up.  I’d like to deploy the app and then npm update on the server.The issue is the app host resets the container because a ports not listening in certain amount of time that can’t be tweaked to any significant number.Sent from my iPhoneOn Mar 13, 2024, at 3:07 PM, Yerden Bulanbayev @.***> wrote: Hello, if someone have troubles like I had there is a way without using zip and unzip name: Build and deploy Node.js app to Azure Web App

env: AZURE_WEBAPP_PACKAGE_PATH: './build'

on: push: branches:

jobs: build-and-deploy: runs-on: ubuntu-latest

steps:
  - uses: ***@***.***

  - name: Set up Node.js version
    uses: ***@***.***
    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: 'Deploy to Azure Web App'
    id: deploy-to-webapp
    uses: ***@***.***
    with:
      app-name: 'app-name'
      slot-name: 'Production'
      publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_YOUR_SECRET }}
      package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

This way took only 10 minutes, 5 minutes to build and other 5 to deploy. Also you have to add startup command in your configuration: pm2 serve /home/site/wwwroot/ --no-daemon --spa image.png (view on web)

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

amsimon commented 4 months ago

@Yerden01

Shouldn't your startup command be pm2 serve /home/site/wwwroot/build --no-daemon --spa ?

Yerden01 commented 4 months ago

@amsimon I am copying only my build folder to azure and I think that's why it is fast)

kjxbyz commented 4 months ago

The alternative for me was to use docker for deployment.

name: Deploy To Azure

#on:
# push:
#   tags:
#     - 'v*'

env:
  NODE_VERSION: '14.x'

jobs:
  build-and-deploy:
    name: Build and Deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
        with:
          token: ${{ secrets.GH_TOKEN }}
          submodules: true
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ env.NODE_VERSION }}
      - uses: pnpm/action-setup@v2.0.1
        name: Install pnpm
        with:
          version: 7
          run_install: false
      - name: Docker login
        uses: azure/docker-login@v1
        with:
          login-server: xxx.azurecr.io
          username: ${{ secrets.AZURE_REGISTRY_USERNAME }}
          password: ${{ secrets.AZURE_REGISTRY_PASSWORD }}
      - name: Docker build
        run: |
          docker build . -t xxx.azurecr.io/imagename:${{ github.sha }}
          docker push xxx.azurecr.io/imagename:${{ github.sha }}
      - name: Deploy to Azure WebApp
        uses: azure/webapps-deploy@v2
        with:
          app-name: ${{ secrets.AZURE_WEBAPP_NAME }}
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          images: 'xxx.azurecr.io/imagename:${{ github.sha }}'
ShilpiRachna1 commented 3 months ago

I apologize for all the inconvenience due to this issue. We will start working on resolving this issue on priority. Thanks!

GovindKarthikeyan commented 3 months ago

@dennisameling You should never, ever, deploy your node modules folder to production. Any given package can open up a security vulnerability even if you are not using that function in your code. Use a build solution like Webpack or similar.

When you do SSR on your app using NextJs or Remix frameworks you have to deploy with node_modules which is a pain right now with Azure deployment.

GovindKarthikeyan commented 3 months ago

We can't use WEBSITE_RUN_FROM_PACKAGE="1" because it makes the whole wwwroot/deploy folder readonly, with NextJs persistent cache it is impossible to clear the cache with this setting. Microsoft folks please rewrite Kudo Sync tool that's terribly slow right now, pls.

llama-one commented 2 months ago

Zipping the package and un-zipping it definitely is a step in the right direction but the real issue as someone mentioned before is that Kuru unzips everything in one place and then copies it over to the right path. Relevant line from the logs:

Kudu sync from: '/tmp/zipdeploy/extracted' to: '/home/site/wwwroot'

Since node modules can have tens of thousands of file, this takes A LOT of time.

The WEBSITE_RUN_FROM_PACKAGE="1" is just not a solution.

If you are running a node.js backend app, this is a really big problem.

llama-one commented 2 months ago

To anyone coming to this package here are a couple of pointers that will definitely improve you build speeds:

In my case, I'm deploying a node.js express-based app that serves static content (a react app) as well as act as an API server for the SPA. Doing the above steps cut down my build time from ~30 mins to about ~1 min.

amsimon commented 2 weeks ago

@ShilpiRachna1 What is the progress on this issue? Deploys are at 50 minutes long for a simple Node app right now which is completely unacceptable.

gms10ur commented 2 weeks ago
image

I'm so tired....