如何通过JavaScript实现Heroku服务器上的文件持久化存储?
问题原因
文件自动消失是Heroku的平台特性导致的,和你的代码逻辑无关:Heroku运行应用的dyno容器使用临时文件系统,存储内容和容器生命周期完全绑定。每次应用重新部署、dyno休眠唤醒、Heroku例行维护重启(每天至少触发一次),容器都会被销毁重建,重建后文件系统会完全重置为你git推送时的初始状态,所有运行时写入的文件(包括你上传到/files目录的内容)都会被清空。
不存在任何修改Heroku配置、安装本地npm包的方式能让dyno本地文件持久化,这是平台底层的硬限制,不用在这个方向试错。
免费解决方案
以下方案都不需要额外付费,足够个人项目使用:
方案1:Heroku Postgres免费实例存小文件
如果你存储的都是单文件几MB以内的小文件,总容量不超过1G,直接用Heroku官方免费的Postgres附加组件就行,不用额外对接第三方服务:
- 在项目目录执行命令挂载免费数据库实例:
heroku addons:create heroku-postgresql:hobby-dev - 安装pg依赖:
npm install pg - 修改上传逻辑:去掉原来写本地文件的代码,把文件的buffer、文件名、文件类型存在数据库的bytea字段里,访问文件时从数据库读二进制流返回即可。
这个方案优点是配置简单,全在Heroku生态内完成;缺点是不适合存大文件,高并发下性能一般。
方案2:免费对象存储(推荐,适配全场景)
如果要存大文件、需要更好的访问性能,选带永久免费额度的对象存储是最优解,改造成本很低:
- Cloudflare R2有永久免费额度:10GB存储空间,每月100万次读请求、10万次写请求,不收出站流量费,个人用基本不会产生费用,完全兼容S3 API。
- 对接只需要装
@aws-sdk/client-s3依赖,把你原来代码里file.mv写本地路径的逻辑,替换成上传文件到R2存储桶即可,原有业务逻辑几乎不用改。 - 你提到的S3对新用户也有12个月的免费额度(每月5GB存储),如果已经领过AWS新用户福利,直接选R2就可以。
避坑提醒
不要用网上教程里说的第三方buildpack挂载网络磁盘到Heroku本地目录的方案,这类方案稳定性极差,dyno重启时很容易挂载失败、丢文件,配置也很繁琐,不要在正式环境用。
内容的提问来源于stack exchange,提问作者AmazingCoder
相关产品推荐
相关产品推荐

