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

Azure容器部署Node.js Express服务后404及启动失败问题排查

问题

将基于TypeScript开发的Node.js+Express应用部署到Azure App Service后,出现以下异常:

  • 访问https://appurl/server-running端点返回404错误,但https://appurl/assets/img.png等静态资源、根路径页面可正常访问
  • 配置web.config试图通过iisnode将请求重定向到server.mjs,但未生效,且无法查看IISNODE日志
  • 通过Kudu手动启动node server.mjs后,访问端点仍返回404,Express服务无法自动启动,需手动调用
  • 当前CORS设为*,使用Azure免费层,无法在容器内安装内容,Node版本为v20.18.0

附相关配置片段:

package.json片段

"type": "module",
  "main": "server.mjs",
  "scripts": {
    "dev": "vite",
    "mainbuild": "tsc -b && vite build && npx tsc -b tsconfig.server.json",
    "build": " npm run mainbuild && npm run rename.mjs && npm run postbuild",
    "postbuild": "cp web.config dist/",
    "rename.mjs": "renamer --find '/\\.js$/' --replace '.mjs' './dist/*.js'",
    "lint": "eslint .",
    "preview": "vite preview",
    "start": "concurrently \"node server.mjs\" \"vite\""
  }

web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="iisnode" path="server.mjs" verb="*" modules="iisnode" resourceType="Unspecified" />
    </handlers>
    <defaultDocument>
      <files>
        <clear />
        <add value="server.mjs" />
      </files>
    </defaultDocument>
    <iisnode>
      <nodeProcessCommandLine>node</nodeProcessCommandLine>
      <loggingEnabled>true</loggingEnabled>
    </iisnode>
  </system.webServer>
</configuration>

server.ts(编译后重命名为mjs)

import express from "express";
import cors from "cors";
import {existsSync} from "fs";
const {FRONTEND_URL, EXPRESS_SERVER_CONFIG} = await import(
  existsSync("./config.ts") ? "./config.ts" : "./config.mjs"
);
import JSONBig from "json-bigint";
const app = express();

app.use(
  cors({
    origin: FRONTEND_URL, 
    methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], 
    credentials: true,
  })
);
app.use(bodyParser.json());

app.get("/server-running", (req, res) => {
  console.log(req.baseUrl);
  res.send("Server is Running");
});

app.use((req, res) => {
  res.status(404).json({error: "404"});
});

const PORT = process.env.PORT || 3000; 
app.listen(PORT, () => {
  console.log(
    `Server is running on port ${PORT} front end url: ${FRONTEND_URL}`
  );
});

排查与解决方案

1. 修复Express服务启动错误

你的server.ts中使用了bodyParser.json()但未导入bodyParser模块,这会导致Node.js运行时抛出ReferenceError: bodyParser is not defined,服务根本无法正常启动。即使手动执行node server.mjs,服务也会崩溃,自然无法响应请求。

修复方法:
替换原有的bodyParser.json()调用为Express内置的JSON解析器(Express 4.16+已内置该功能):

// 替换原有的app.use(bodyParser.json());
app.use(express.json());

2. 完善web.config的URL重写规则

当前web.config仅配置了iisnode处理server.mjs文件,但没有将API请求转发到server.mjs。Azure App Service的IIS会优先处理静态资源,对于/server-running这类路径,IIS会当成静态文件查找,找不到就返回404,不会转发给Express服务。

修改后的web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="iisnode" path="server.mjs" verb="*" modules="iisnode" resourceType="Unspecified" />
    </handlers>
    <!-- 添加URL重写规则,将非静态资源请求转发给Express -->
    <rewrite>
      <rules>
        <!-- 排除静态资源路径,避免转发 -->
        <rule name="StaticFiles" stopProcessing="true">
          <match url="^(assets|static)/.*$" />
          <action type="None" />
        </rule>
        <!-- 根路径指向前端首页 -->
        <rule name="Root" stopProcessing="true">
          <match url="^$" />
          <action type="Rewrite" url="index.html" />
        </rule>
        <!-- 所有其他请求转发到server.mjs处理 -->
        <rule name="ExpressRoutes" stopProcessing="true">
          <match url="(.*)" />
          <action type="Rewrite" url="server.mjs" />
        </rule>
      </rules>
    </rewrite>
    <defaultDocument>
      <files>
        <clear />
        <add value="index.html" />
        <add value="server.mjs" />
      </files>
    </defaultDocument>
    <iisnode>
      <nodeProcessCommandLine>node</nodeProcessCommandLine>
      <loggingEnabled>true</loggingEnabled>
      <!-- 指定日志存储路径,方便后续排查 -->
      <logDirectory>iisnode</logDirectory>
    </iisnode>
  </system.webServer>
</configuration>

3. 配置正确的启动命令

你的package.json中的start脚本是开发环境用的,同时启动node server.mjs和vite,生产环境不需要启动vite。Azure App Service默认执行npm start,需确保启动脚本仅运行Express服务,或直接在Azure门户配置启动命令。

两种配置方式:

  • 修改package.json的start脚本:
    "start": "node server.mjs"
    
  • 或在Azure门户的App Service -> 配置 -> 常规设置中,设置启动命令为:
    node server.mjs
    
    注意:如果server.mjs在dist目录下,启动命令应为node dist/server.mjs,同时需确保部署后的工作目录正确。

4. 确认部署文件结构

通过Kudu文件浏览器检查:

  • web.config位于部署根目录(或dist目录,需与Azure部署路径对应)
  • server.mjs和静态资源文件路径正确
  • CI/CD部署时,确保部署的是dist目录下的文件,而非项目根目录

5. 查看日志排查问题

无法查看IISNODE日志时,可通过以下方式获取日志:

  • 在Azure门户的App Service -> 日志 -> 日志流中查看实时日志
  • 通过Kudu访问LogFiles/iisnode目录,查看iisnode日志文件
  • 手动启动server.mjs时,在Kudu CLI中查看输出的错误信息,确认服务是否正常启动

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:48:09