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

如何解决cyclic.sh只读文件系统下Express文件上传失败问题?

问题分析

错误EROFS: read-only file system明确说明Cyclic.sh运行环境中,/var/task目录是只读的——这是Cyclic的架构限制,应用代码所在的目录不允许写入操作。此前Heroku的dyno提供临时可写文件系统(虽然重启后数据丢失),本地环境完全可控,所以相同代码能正常运行,但迁移到Cyclic后就触发了权限错误。

解决方案

Cyclic.sh提供了内置云存储服务,必须改用该服务处理文件上传,不能再依赖本地磁盘存储(比如Multer的DiskStorage)。

步骤1:安装Cyclic存储SDK

npm install @cyclic.sh/s3

步骤2:替换Multer存储配置

放弃DiskStorage,改用内存存储接收文件,再将文件上传到Cyclic云存储:

const express = require('express')
const router = express.Router()
const multer = require('multer')
const { Storage } = require('@cyclic.sh/s3')

// 初始化Cyclic存储(CYCLIC_BUCKET_NAME由平台自动注入环境变量)
const cyclicStorage = new Storage(process.env.CYCLIC_BUCKET_NAME)

// 用内存存储接收上传文件(避免写入本地只读目录)
const multerConfig = multer({ storage: multer.memoryStorage() })

// 修改上传路由
router.post('/cards/upload', multerConfig.single('your-file-field-name'), async (req, res) => {
  if (!req.file) {
    return res.status(400).send('未选择上传文件')
  }

  try {
    // 将文件上传到Cyclic存储的uploads目录下
    const uploadResult = await cyclicStorage.put(
      `uploads/${req.file.originalname}`,
      req.file.buffer,
      { ContentType: req.file.mimetype }
    )

    // 返回存储的文件URL供后续使用
    res.status(200).json({ 
      message: '上传成功',
      fileUrl: uploadResult.url 
    })
  } catch (err) {
    console.error('上传失败:', err)
    res.status(500).send('文件上传失败')
  }
})

module.exports = router

关键注意点

  • Cyclic的环境变量CYCLIC_BUCKET_NAME会自动配置,无需手动填写
  • 上传的文件会持久存储在Cyclic云存储中,不会像Heroku临时存储那样重启丢失
  • 本地开发时可保留DiskStorage配置,通过环境变量判断切换:
    const multerStorage = process.env.NODE_ENV === 'production' 
      ? multer.memoryStorage() 
      : multer.diskStorage({
          destination: (req, file, cb) => {
            cb(null, './public/uploads')
          },
          filename: (req, file, cb) => {
            cb(null, file.originalname)
          }
        })
    const upload = multer({ storage: multerStorage })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:05:24