Next.js项目部署至Vercel平台时上传文件到服务器出现EROFS报错
Vercel图片上传报错处理方案
报错根因
2021-09-20T15:33:39.427Z 58fb3aa3-54bb-464e-8a68-fb876ded6cdc ERROR Error: EROFS: read-only file system, mkdir '/var/task/public' at Object.mkdirSync (fs.js:1009:3) at sync (/var/task/node_modules/mkdirp/index.js:72:13) at Function.sync (/var/task/node_modules/mkdirp/index.js:78:24) at new DiskStorage (/var/task/node_modules/multer/storage/disk.js:21:12) at Function.module.exports [as diskStorage] (/var/task/node_modules/multer/storage/disk.js:65:10) at Object.2439 (/var/task/.next/server/pages/api/uploads.js:32:38) at __webpack_require__ (/var/task/.next/server/webpack-runtime.js:25:42) at __webpack_exec__ (/var/task/.next/server/pages/api/uploads.js:102:52) at /var/task/.next/server/pages/api/uploads.js:103:28 at Object.<anonymous> (/var/task/.next/server/pages/api/uploads.js:106:3) { errno: -30, syscall: 'mkdir', code: 'EROFS', path: '/var/task/public' } RequestId: 58fb3aa3-54bb-464e-8a68-fb876ded6cdc Error: Runtime exited with error: exit status 1 Runtime.ExitError
这个报错是Vercel Serverless运行环境的固有特性导致的:Vercel的Serverless函数运行时,只有/tmp目录具备临时读写权限,其余所有目录均为只读状态,不允许创建目录或写入文件。本地运行正常是因为本地开发环境没有这类目录权限限制,你的代码中配置multer的磁盘存储路径指向了public目录,部署后尝试在只读路径创建目录就会触发该错误。
解决方案
- 临时调试方案:将multer的diskStorage存储路径修改为
/tmp目录即可解决写入报错,但是/tmp目录为临时存储,Serverless函数执行完成后该目录的所有文件都会被清空,无法持久化存储上传的图片,仅适合调试使用。 - 生产可用方案:放弃将上传的图片存储到Vercel本地的逻辑,改用第三方对象存储服务保存上传的文件。调整上传逻辑为:接口接收到前端上传的文件流后,直接将文件流上传到你选择的对象存储服务,拿到公网可访问的资源URL后返回给前端即可,全程不需要写入Vercel本地磁盘,完全适配Vercel的运行环境限制。
- 优化方案:如果不想经过后端接口转发文件流,也可以直接在前端请求对象存储的临时上传凭证,前端直接把文件上传到对象存储服务,进一步减少Vercel接口的带宽消耗和执行时长。
内容的提问来源于stack exchange,提问作者Navid Nourani
相关产品推荐
相关产品推荐

