Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy very slow using NodeJs #229

Open
kimmy-wang opened this issue May 1, 2022 · 53 comments
Open

Deploy very slow using NodeJs #229

kimmy-wang opened this issue May 1, 2022 · 53 comments
Assignees
Labels
backlog Planned for future

Comments

@kimmy-wang
Copy link

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

@github-actions
Copy link

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

@github-actions github-actions bot added the idle label May 15, 2022
@rabollin rabollin added backlog Planned for future and removed need-to-triage idle labels Jul 27, 2022
@rabollin
Copy link

Triaged and added to backlog.

@dennisameling
Copy link

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
Copy link

sven5 commented Dec 22, 2022

@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
Copy link

oshihirii commented Dec 26, 2022

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
Copy link
Contributor

shpraka commented Jan 9, 2023

@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
Copy link
Contributor

shpraka commented Jan 9, 2023

@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
Copy link

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
Copy link

@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
Copy link
Contributor

shpraka commented Jan 11, 2023

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

@hharb3
Copy link

hharb3 commented Jan 11, 2023

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
Copy link

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

@oshihirii
Copy link

oshihirii commented Jan 14, 2023

@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
Copy link
Contributor

shpraka commented Jan 16, 2023

@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
Copy link

@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
Copy link

oshihirii commented Jan 16, 2023

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

  • the most recent versions of the actions
  • the contents required to enable a fast build and deploy (not a slow build and deploy)

@shpraka
Copy link
Contributor

shpraka commented Jan 16, 2023

@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
Copy link
Contributor

shpraka commented Jan 16, 2023

Updated the readme as part #287

@dennisameling
Copy link

Thanks @shpraka! Appreciate it!

@tefkah
Copy link

tefkah commented Jan 25, 2023

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
Copy link

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

@KuNman
Copy link

KuNman commented Apr 28, 2023

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

@NoCopy
Copy link

NoCopy commented May 3, 2023

@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.

@Casperjuel
Copy link

@sgollapudi77 Any updates on this issue? 👀

@amhed-dtg
Copy link

We ended up dockerizing everything

@sgollapudi77
Copy link
Contributor

sgollapudi77 commented Oct 23, 2023

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

  • Based on our analysis of the current workflow file, we noticed that a significant amount of time was spent transferring the build artifact from the build step to the deploy step. Thanks to the suggestions from community members (@MoatezNG, @danmana), we found that compressing the artifact during the build step and decompressing it during the deploy step greatly reduces this time.
  • You can refer to the updated actions-workflow-samples/AppService/node.js-webapp-on-azure.yml at master · Azure/actions-workflow-samples (github.com) workflow file. Here is the glimpse of the changes:
    • Updates to build step

      - name: Zip artifact for deployment
       run: zip release.zip ./* -r
      - name: Upload artifact for deployment job
       uses: actions/upload-artifact@v3
       with:
         name: node-app
         path: release.zip
      
    • Updates to deploy step

      - name: Unzip artifact for deployment
        run: unzip release.zip
      

We’ve also updated the Azure Portal to include these changes, so all new integrations will benefit from this optimized workflow file. We appreciate your patience throughout this process and look forward to hearing your feedback. Please feel free to share your thoughts in the comments or reactions. Thank you!

@StephanBis
Copy link

@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
Copy link

@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
Copy link

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
Copy link

efischler commented Mar 8, 2024

@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
Copy link

amsimon commented Mar 13, 2024

@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
Copy link

mweel1 commented Mar 13, 2024 via email

@Yerden01
Copy link

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
Copy link

mweel1 commented Mar 13, 2024 via email

@amsimon
Copy link

amsimon commented Mar 13, 2024

@Yerden01

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

@Yerden01
Copy link

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

@kjxbyz
Copy link

kjxbyz commented Mar 14, 2024

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
Copy link
Collaborator

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

@GovindKarthikeyan
Copy link

GovindKarthikeyan commented Apr 12, 2024

@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
Copy link

GovindKarthikeyan commented Apr 12, 2024

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
Copy link

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
Copy link

llama-one commented May 1, 2024

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

  • Use a front-end build tool like webpack or vite and use npm build to create the smallest possible production build.
  • Run npm prune (npm prune --omit-dev) after npm build. Prune will remove any dependencies that are not required for production from node_modules. The caveat to this is that you correctly specify what's not required at run time by placing those dependencies in the devDependencies section of your package.json.

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
Copy link

amsimon commented Jun 22, 2024

@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
Copy link

gms10ur commented Jun 25, 2024

image

I'm so tired....

@PauloRodrigues33
Copy link

Same issue here, mora than 20 min to deploy a Hello Word nextJS app.
For now, i'm switching my Application to container mode.

@nikita-s-sauce
Copy link

nikita-s-sauce commented Aug 6, 2024

  • ~20-40m build
  • node_modules - 29 886 items, totalling 512,7 MB
  • I am using zip deploy
  • The main problem is that node_modules contains a lot of small files

Waiting for some solution, for now only possible one is to move to container mode OR to clean node_modules manually

     - name: Clean up build artifacts
        run: |
          rm -rf ${{ env.NEXTJS_BUILD_PATH }}/cache
          rm -rf node_modules/@next/swc-linux-x64-musl
          rm -rf node_modules/@next/swc-linux-x64-gnu
          ...

@dylanmeivis
Copy link

Hi everyone using Next.js,

I was struggling with this same issue deploying my Next.js application to an azure app service. I managed to drastically reduce the deploy time to 1m 4s.

Image

Solution

I am now using the standalone feature from Next.js and only copy the required files to my artifact. I set a custom start command to use pm2 to start my app with the server.js file inside the standalone folder.

next.config.js

/** @type {import("next").NextConfig} */
const config = {
  output: "standalone",
};

export default config;

Workflow file

name: Build and deploy to Production

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:  
      - uses: actions/checkout@v4

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: '20.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present

      - name: Zip artifact for deployment
        run: |
          mkdir -p release
          cp next.config.js release
          cp -r public release
          cp package.json release
          cp -r .next/standalone release
          cp -r .next/static release
          zip -r release.zip release

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        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 }}
    permissions:
      id-token: write #This is required for requesting the JWT

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: node-app

      - name: Unzip artifact for deployment
        run: unzip release.zip
      
      - name: Login to Azure
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID}}
          tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID }}
          subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID}}

      - name: 'Deploy to Azure Web App'
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v3
        with:
          app-name: 'app'
          slot-name: 'Production'
          startup-command: 'pm2 start release/standalone/server.js --no-daemon'
          package: .

@MiloTischler
Copy link

Is there any update? Unfortunately WEBSITE_RUN_FROM_PACKAGE="1" is not an option for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog Planned for future
Projects
None yet
Development

No branches or pull requests