Azure Pipeline部署Next.js至App Service提示无页面访问权限
部署故障排查结论
你的流水线配置存在3处和Windows App Service托管Next.js规则不匹配的错误,直接导致部署后缺少启动依赖、IIS无法识别Node应用,最终出现无web.config、访问报403无权限的问题:
- 打包范围错误:构建阶段仅压缩了
.next目录,遗漏了Next.js启动必需的package.json、next.config.js、public静态资源目录、生产依赖node_modules等核心文件,应用根本没有可执行的启动入口。 - 部署任务参数错误:目标App Service为Windows系统,但部署任务误用了Linux专属的
packageForLinux入参,且未明确指定应用类型为Windows Web App,部署流程不会自动触发IIS Node托管规则(即web.config)的生成逻辑。 - 无效步骤冗余:你使用的是Windows自托管代理,却在步骤里执行Linux专属的
sudo apt-get install zip命令,该步骤在Windows环境下完全无法生效,只是因为未配置步骤错误中断规则,才没有阻塞流水线运行。
具体修复步骤
1. 调整构建阶段的打包逻辑
在npm run build步骤后新增生产依赖安装步骤,只保留运行时需要的依赖减少包体积:
- script: npm install --production --force displayName: 'Install production dependencies'
修改ArchiveFiles@2任务的打包源,不要只打包.next目录,改为打包整个项目根目录,同时排除不需要的缓存、代码目录:
- task: ArchiveFiles@2 inputs: rootFolderOrFile: '$(System.DefaultWorkingDirectory)' includeRootFolder: false archiveType: 'zip' archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip' replaceExistingArchive: true verbose: true # 排除非运行必需的文件 excludeFiles: | **/.git/** **/.next/cache/** **/test/** **/*.md **/.eslintrc* **/tsconfig.json
直接删掉最开始安装zip的CmdLine步骤,Windows环境下ArchiveFiles任务不依赖系统zip命令,该步骤完全多余。
如果需要进一步压缩部署包体积,可以在
next.config.js中配置output: 'standalone',构建完成后Next.js会自动生成可独立运行的产物目录,此时仅需打包.next/standalone、.next/static、public三个目录即可,不需要上传全量node_modules。
2. 修正部署任务参数
将AzureRmWebAppDeployment@4任务的参数调整为适配Windows App Service的配置,明确指定启动命令,开启web.config自动生成:
- task: AzureRmWebAppDeployment@4 inputs: ConnectionType: 'AzureRM' azureSubscription: '***********' appType: 'webAppWindows' # 明确指定为Windows Web应用 WebAppName: 'fpt-capstone-client' package: '$(System.WorkFolder)/1/package/$(Build.BuildId).zip' # 替换Linux专属的packageForLinux参数 enableCustomDeployment: true startUpCommand: 'node node_modules/next/dist/bin/next start' # 指定Next.js启动命令
如果自动生成的web.config不符合预期,可以在项目根目录提前放入适配Next.js的标准web.config文件,打包时会随项目一起上传,直接被IIS识别,参考配置如下:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers> <add name="iisnode" path="node_modules/next/dist/bin/next" verb="*" modules="iisnode" /> </handlers> <rewrite> <rules> <rule name="Next.js" stopProcessing="true"> <match url="(.*)" /> <action type="Rewrite" url="node_modules/next/dist/bin/next" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
附报错日志截图

内容的提问来源于stack exchange,提问作者Vo Nhu Khang
相关产品推荐
相关产品推荐

