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

本地Git部署Express至Azure App Service失败:依赖链接出错

问题:Express.js应用部署Azure App Service时依赖链接阶段失败

尝试通过本地Git将Express.js应用部署至Azure App Service,本地运行正常,但部署时在依赖链接阶段失败。应用使用80端口,部署未包含node_modules,public文件夹内有React构建产物。

部署日志

2024-06-08T19:51:30.752150035Z   /  _  \ __________ _________   ____  
2024-06-08T19:51:30.752154235Z  /  /_\  \\___   /  |  \_  __ \_/ __ \ 
2024-06-08T19:51:30.752157335Z /    |    \/    /|  |  /|  | \/\  ___/ 
2024-06-08T19:51:30.752160335Z \____|__  /_____ \____/ |__|    \___  >
2024-06-08T19:51:30.752163435Z         \/      \/                  \/ 
2024-06-08T19:51:30.752166335Z A P P   S E R V I C E   O N   L I N U X
2024-06-08T19:51:30.752169535Z 
2024-06-08T19:51:30.752172235Z Documentation: http://aka.ms/webapp-linux
2024-06-08T19:51:30.752175535Z NodeJS quickstart: https://aka.ms/node-qs
2024-06-08T19:51:30.752178335Z NodeJS Version : v18.19.1
2024-06-08T19:51:30.752181035Z Note: Any data outside '/home' is not persisted
2024-06-08T19:51:30.752184035Z 
2024-06-08T19:51:31.193914248Z Starting OpenBSD Secure Shell server: sshd.
2024-06-08T19:51:31.244489951Z Starting periodic command scheduler: cron.
2024-06-08T19:51:31.276188603Z Could not find build manifest file at '/home/site/wwwroot/oryx-manifest.toml'
2024-06-08T19:51:31.280345636Z Could not find operation ID in manifest. Generating an operation id...
2024-06-08T19:51:31.280378236Z Build Operation ID: 41e9c42e-d2f1-434c-a412-46c9c404420a
2024-06-08T19:51:31.485113164Z Environment Variables for Application Insight's IPA Codeless Configuration exists..
2024-06-08T19:51:31.507160140Z Writing output script to '/opt/startup/startup.sh'
2024-06-08T19:51:31.544600937Z Running #!/bin/sh
2024-06-08T19:51:31.544629338Z 
2024-06-08T19:51:31.544633938Z # Enter the source directory to make sure the script runs where the user expects
2024-06-08T19:51:31.544637538Z cd "/home/site/wwwroot"
2024-06-08T19:51:31.544640938Z 
2024-06-08T19:51:31.544644138Z export NODE_PATH=/usr/local/lib/node_modules:$NODE_PATH
2024-06-08T19:51:31.544647438Z if [ -z "$PORT" ]; then
2024-06-08T19:51:31.544650738Z      export PORT=8080
2024-06-08T19:51:31.544654538Z fi
2024-06-08T19:51:31.544657638Z 
2024-06-08T19:51:31.544660738Z PATH="$PATH:/home/site/wwwroot" cd prodoslo1 && yarn install && yarn run prod
2024-06-08T19:51:31.955441605Z yarn install v1.22.15
2024-06-08T19:51:32.085875742Z [1/5] Validating package.json...
2024-06-08T19:51:32.089607272Z [2/5] Resolving packages...
2024-06-08T19:51:32.662441527Z [3/5] Fetching packages...
2024-06-08T19:51:52.373047412Z info fsevents@2.3.3: The platform "linux" is incompatible with this module.
2024-06-08T19:51:52.373369015Z info "fsevents@2.3.3" is an optional dependency and failed compatibility check. Excluding it from installation.
2024-06-08T19:51:52.395040552Z [4/5] Linking dependencies...
2024-06-08T19:51:53.245750111Z error Could not write file "/home/site/wwwroot/prodoslo1/yarn-error.log": "EROFS: read-only file system, open '/home/site/wwwroot/prodoslo1/yarn-error.log'"
2024-06-08T19:51:53.246134615Z error An unexpected error occurred: "EROFS: read-only file system, mkdir '/home/site/wwwroot/prodoslo1/node_modules'".
2024-06-08T19:51:53.246313917Z info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

package.json配置

"dependencies": {
    "@babel/cli": "^7.18.10",
    "@babel/core": "^7.18.13",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.18.10",
    "@babel/register": "^7.18.9",
    "@sentry/node": "^7.58.1",
    "axios": "^1.3.5",
    "babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.20.0",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "date-fns": "^2.30.0",
    "debug": "^4.3.4",
    "dotenv": "^16.0.1",
    "exceljs": "^4.3.0",
    "express": "^4.18.1",
    "google-auth-library": "^8.9.0",
    "google-spreadsheet": "^4.0.2",
    "googleapis": "^120.0.0",
    "jsonwebtoken": "^8.5.1",
    "lodash": "^4.17.21",
    "mathjs": "^11.11.1",
    "moment": "^2.29.4",
    "morgan": "^1.10.0",
    "multer": "^1.4.5-lts.1",
    "mysql2": "^2.3.3",
    "node-cron": "^3.0.2",
    "nodemailer": "^6.9.1",
    "nodemon": "^2.0.19",
    "npm-run-all": "^4.1.5",
    "query-string": "^8.1.0",
    "rimraf": "^5.0.0",
    "sequelize": "^6.37.1",
    "socket.io": "^4.7.2",
    "swagger-autogen": "^2.23.7",
    "swagger-ui-express": "^5.0.0",
    "sweetalert2": "^11.6.10",
    "twilio": "^4.19.3",
    "uuid": "^9.0.0",
    "ws": "^8.15.1",
    "xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz"
  },
  "lint-staged": {
    "*.{js}": [
      "yarn run format",
      "git add ."
    ]
  },
  "devDependencies": {
    "@babel/plugin-syntax-import-assertions": "^7.22.5",
    "@babel/plugin-transform-modules-commonjs": "^7.22.5",
    "eslint": "8.22.0",
    "eslint-config-google": "^0.14.0",
    "husky": "^8.0.1",
    "jest": "^28.1.3",
    "lint-staged": "^13.0.3",
    "prettier": "^2.7.1"
  },
  "jest": {
    "testEnvironment": "node"
  }

排查与解决方案

核心问题定位

日志中的错误EROFS: read-only file system, mkdir '/home/site/wwwroot/prodoslo1/node_modules'明确指向:Azure App Service的/home/site/wwwroot目录在运行时为只读状态,而部署脚本直接在此目录执行yarn install,尝试创建node_modules目录和写入日志文件,触发权限错误。

解决方案步骤

  1. 修改启动命令,将依赖安装到可写目录
    Azure的/home目录是可持久化且具备写入权限的目录,可将依赖安装到该目录下。修改启动命令为:

    cd /home/site/wwwroot/prodoslo1 && yarn install --modules-folder /home/node_modules && yarn run prod
    

    或者通过指定工作目录的方式:

    cd /home && yarn install --cwd /home/site/wwwroot/prodoslo1 && cd /home/site/wwwroot/prodoslo1 && yarn run prod
    
  2. 配置NODE_PATH环境变量
    在Azure门户的应用服务配置页面,添加环境变量:

    • NODE_PATH=/home/node_modules
      让Node.js能够找到安装在/home目录下的依赖包。
  3. 提前构建依赖,避免运行时安装
    更高效的方式是在本地完成依赖安装和构建,再部署到Azure:

    • 本地执行yarn install --production(仅安装生产依赖,减少体积)
    • 调整.gitignore,允许提交node_modules目录(或针对部署分支单独配置)
    • 将包含node_modules、应用代码、public构建产物的完整项目提交到Git,重新部署
  4. 修正启动命令配置
    若已提前安装依赖,可直接在Azure门户的"配置">"常规设置">"启动命令"中设置:

    cd /home/site/wwwroot/prodoslo1 && yarn run prod
    

额外注意事项

  • 端口适配:Azure会动态分配端口,需确保Express应用监听PORT环境变量而非硬编码的80端口,修改代码:
    const port = process.env.PORT || 80;
    app.listen(port, () => {
      console.log(`Server running on port ${port}`);
    });
    
  • 可选依赖警告:日志中fsevents的兼容性警告属于正常情况,该依赖为macOS专属,Linux环境下会自动跳过,不影响应用运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 18:02:31