You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Github Actions部署Nest.js至Azure Web App异常:wwwroot为空但部署显示成功

Nest.js API部署到Azure Web App后wwwroot目录为空的问题排查与修复

问题描述

我有一个Nest.js API,之前通过Github Actions部署到Azure Web Service一切正常,但现在部署日志显示成功,Azure Web App的wwwroot目录却为空。

当前配置

Github Actions工作流文件

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

on:
  push:
    branches:
      - dev
    # paths-ignore:
    #   - 'README.md'
    #   - '.husky'
    #   - '.github/**'
    #   - '**/*.csv'
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4.1.1

      - name: Set up Node.js version
        uses: actions/setup-node@v4.0.2
        with:
          node-version: '20.4.0'

      # - name: npm install, build, and test
      #   run: |
      #     npm install -g @nestjs/cli
      #     npm install
      #     npm run build

      - name: Zip artifact for deployment
        run: |
          zip -r release.zip . \
          -x "*.git/*" \
          -x ".vscode/*" \
          -x "src/*" \
          -x "test/*" \
          -x "README.md" \
          -x ".env" \
          -x ".env.example" \
          -x ".env.local" \
          -x ".gitignore" \
          -x ".prettierrc" \
          -x "tsconfig.build.json" \
          -x "tsconfig.json" \
          -x ".github/*"

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4.3.1
        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.1.4
        with:
          name: node-app

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

      - name: Login to Azure
        uses: Azure/login@v2.0.0
        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.0.1
        with:
          app-name: 'dev-api'
          slot-name: 'production'
          package: 'release.zip'
          # type: 'zip'
          # clean: true
          # restart: true

      - name: Logout
        run: |
          az logout

.deployment文件

[config]
SCM_DO_BUILD_DURING_DEPLOYMENT=true

web.config文件

<?xml version="1.0" encoding="utf-8"?>
<!--
     This configuration file is required if iisnode is used to run node processes behind
     IIS or IIS Express.
-->
<configuration>
    <system.webServer>
        <webSocket enabled="false" />
        <handlers>
            <add name="iisnode" path="dist/main.js" verb="*" modules="iisnode" />
        </handlers>
        <rewrite>
            <rules>
                <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
                    <match url="^dist/main.js/debug[/]?" />
                </rule>

                <rule name="StaticContent">
                    <action type="Rewrite" url="public{REQUEST_URI}" />
                </rule>

                <rule name="DynamicContent">
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
                    </conditions>
                    <action type="Rewrite" url="dist/main.js" />
                </rule>
            </rules>
        </rewrite>

        <security>
            <requestFiltering>
                <hiddenSegments>
                    <remove segment="bin" />
                </hiddenSegments>
            </requestFiltering>
        </security>

        <httpErrors existingResponse="PassThrough" />
    </system.webServer>
</configuration>

部署成功日志

Package deployment using OneDeploy initiated.
{
  id: '7e616a05-6826-47c8-9bf7-bb7f3b1b6ad7',
  status: 4,
  status_text: '',
  author_email: 'N/A',
  author: 'N/A',
  deployer: 'OneDeploy',
  message: 'OneDeploy',
  progress: '',
  received_time: '2024-04-17T12:04:00.9090509Z',
  start_time: '2024-04-17T12:04:02.2551014Z',
  end_time: '2024-04-17T12:04:03.2578212Z',
  last_success_end_time: '2024-04-17T12:04:03.2578212Z',
  complete: true,
  active: true,
  is_temp: false,
  is_readonly: true,
  url: 'https://dev-api.scm.azurewebsites.net/api/deployments/7e616a05-6826-47c8-9bf7-bb7f3b1b6ad7',
  log_url: 'https://dev-api.scm.azurewebsites.net/api/deployments/7e616a05-6826-47c8-9bf7-bb7f3b1b6ad7/log',
  site_name: 'dev-api',
  build_summary: { errors: [], warnings: [] }
}
Deploy logs can be viewed at https://dev-api.scm.azurewebsites.net/api/deployments/7e616a05-6826-47c8-9bf7-bb7f3b1b6ad7/log
Successfully deployed web package to App Service.
App Service Application URL: https://dev-api.azurewebsites.net

问题原因分析

  1. 构建步骤被注释:工作流中npm install, build, and test步骤被注释,导致未生成Nest.js编译产物dist目录,而web.config指向dist/main.js,压缩包缺少核心运行文件。
  2. WEBSITE_RUN_FROM_PACKAGE配置影响:该变量设为true/1时,Azure直接从部署包运行应用,不会解压到wwwroot目录,所以wwwroot为空是预期行为,但如果包本身缺失文件,应用会无法启动。
  3. 压缩包内容不完整:未执行构建步骤,压缩包中无dist目录,也可能缺少package.json等依赖配置文件,导致部署后无法正常运行。

修复步骤

步骤1:恢复构建步骤

取消工作流中构建步骤的注释,确保生成编译产物:

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

(注:若项目依赖已包含@nestjs/cli,可去掉npm install -g @nestjs/cli)

步骤2:调整部署配置

在Azure/webapps-deploy步骤中启用清理和重启,确保部署时替换旧文件并重启应用:

- name: 'Deploy to Azure Web App'
  id: deploy-to-webapp
  uses: Azure/webapps-deploy@v3.0.1
  with:
    app-name: 'dev-api'
    slot-name: 'production'
    package: 'release.zip'
    clean: true
    restart: true

步骤3:处理WEBSITE_RUN_FROM_PACKAGE变量

  • 若希望wwwroot目录可见文件,将该变量设为false或删除,Azure会自动解压部署包到wwwroot。
  • 若保持变量为true,无需在意wwwroot为空,只需确保部署包包含dist、package.json等完整文件。

步骤4:检查部署日志详情

访问日志中的log_url,查看构建和部署过程的详细输出,确认是否有隐藏错误(如依赖安装失败、构建失败)。

验证

修复后重新触发部署,检查:

  • Github Actions工作流是否完整执行构建步骤。
  • 若关闭WEBSITE_RUN_FROM_PACKAGE,确认wwwroot目录存在dist、package.json等文件。
  • 访问应用URL,验证API是否正常响应。

内容的提问来源于stack exchange,提问作者Skel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:38:10