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

Lambda函数运行EventBridge Atlas报EROFS只读文件系统错误

问题背景
  • 需求为在Lambda函数内通过eventbridge-atlas生成AsyncAPI文档后上传至S3存储桶,本地调试时所有功能运行正常:文件默认存储在/tmp目录(Lambda环境自带该可写目录),已在eventbridge-atlas代码中新增逻辑,用于处理/tmp目录下生成文件的上传S3流程。
  • Lambda函数执行时最初运行的命令如下:
npx @asyncapi/generator /tmp/events.yml @asyncapi/html-template -o /tmp --force-write
  • 按预期该命令应将生成的文档写入Lambda的/tmp目录,本地运行时逻辑完全正常,但实际执行抛出如下错误:
2022-06-28T17:46:49.457Z    90c863cb-b7de-4906-a71c-6aad84fd8bd4    INFO    e Error: Command failed: npx @asyncapi/generator /tmp/events.yml @asyncapi/html-template -o /tmp --force-write
Error: EROFS: read-only file system, mkdir '/home/sbx_user1051'
command not found: generator

    at ChildProcess.exithandler (child_process.js:383:12)
    at ChildProcess.emit (events.js:400:28)
    at ChildProcess.emit (domain.js:475:12)
    at maybeClose (internal/child_process.js:1088:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:296:5) {
  killed: false,
  code: 1,
  signal: null,
  cmd: 'npx @asyncapi/generator /tmp/events.yml @asyncapi/html-template -o /tmp --force-write',
  stdout: '',
  stderr: "Error: EROFS: read-only file system, mkdir '/home/sbx_user1051'\n" +
    'command not found: generator\n'
}
  • 初步排查确认:相关逻辑除了写入指定的/tmp目录外,还会尝试在/home/sbx_user1051路径下创建目录,而Lambda环境除/tmp外的文件系统均为只读,因此触发报错。
  • 后续调整方案:修改eventbridge-atlas代码,不再执行bash命令,改为直接引入对应Node模块调用,仍然出现相同错误,完整错误栈如下:
{
    "errorType": "Runtime.UnhandledPromiseRejection",
    "errorMessage": "Error: EROFS: read-only file system, mkdir '/home/sbx_user1051'",
    "reason": {
        "errorType": "Error",
        "errorMessage": "EROFS: read-only file system, mkdir '/home/sbx_user1051'",
        "code": "EROFS",
        "errno": -30,
        "syscall": "mkdir",
        "path": "/home/sbx_user1051",
        "stack": [
            "Error: EROFS: read-only file system, mkdir '/home/sbx_user1051'"
        ]
    },
    "promise": {},
    "stack": [
        "Runtime.UnhandledPromiseRejection: Error: EROFS: read-only file system, mkdir '/home/sbx_user1051'",
        "    at process.<anonymous> (/var/runtime/index.js:35:15)",
        "    at process.emit (events.js:400:28)",
        "    at process.emit (domain.js:475:12)",
        "    at process.emit (/var/task/node_modules/@asyncapi/generator/node_modules/source-map-support/source-map-support.js:516:21)",
        "    at processPromiseRejections (internal/process/promises.js:245:33)",
        "    at processTicksAndRejections (internal/process/task_queues.js:96:32)"
    ]
}
  • 核心诉求:寻找可行的解决方案,确认是否有开发者成功在Lambda函数中部署eventbridge-atlas实现文档自动生成。
解决方案

报错根因是@asyncapi/generator运行时默认读取当前用户主目录路径,尝试在主目录下创建缓存、临时配置目录,Lambda运行时的用户主目录恰好是只读的/home/sbx_user1051,和你指定的输出路径没有关系。
两个可直接落地的方案:

  1. 配置环境变量重定向所有可写路径到/tmp
    在Lambda函数配置中添加以下环境变量,把所有默认写入用户目录的路径全部指向可写的/tmp下:
    • HOME=/tmp
    • NPM_CONFIG_CACHE=/tmp/.npm
    • XDG_CONFIG_HOME=/tmp/.config
    • XDG_CACHE_HOME=/tmp/.cache
      配置完成后,无论是CLI调用还是直接引入Node模块调用,generator都会把缓存、临时文件全部写到/tmp下,不会再访问只读的/home路径。如果Lambda内存配置较小,注意预留/tmp的存储空间,目前Lambda的/tmp目录最大可配置到10G,常规文档生成场景给512M空间完全够用。
  2. 如果方案1仍有少量路径写入报错,提前在Lambda初始化阶段创建软链接
    在函数冷启动的初始化逻辑中加入如下代码,提前把只读的home路径软链到/tmp下:
    const fs = require('fs');
    const { execSync } = require('child_process');
    // 冷启动时执行一次即可
    if (!fs.existsSync('/tmp/home')) {
      execSync('mkdir -p /tmp/home/sbx_user1051');
      execSync('ln -s /tmp/home/sbx_user1051 /home/sbx_user1051');
    }
    
    该方案相当于给要写入的只读路径做透明转发,所有写入/home/sbx_user1051的操作实际都会落到/tmp下,完全兼容所有依赖的路径写入逻辑,不需要修改第三方包源码。

额外注意事项:

  • 不要在Lambda里用npx临时安装依赖,npx会优先将包装到用户目录下,本身就会触发只读问题,直接把@asyncapi/generator、对应模板、eventbridge-atlas的依赖全部安装到项目node_modules中,和业务代码一起打包上传,冷启动速度也更快。
  • 生成完文档上传S3之后,可以主动清理/tmp下生成的临时文件,避免多次调用后/tmp空间占满触发异常。

目前已有不少开发者通过方案1在Lambda上跑通AsyncAPI生成逻辑,不需要修改eventbridge-atlas或者generator的源码,配置完环境变量即可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:06:23