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

NextJS部署GAE报错:EROFS只读文件系统问题求助

解决GAE部署Next.js应用时的只读文件系统错误

看起来你碰到的问题是Google App Engine(GAE)标准环境的只读文件系统限制导致的——GAE里除了/tmp目录外,其他所有部署目录都是只读状态,而你的Next.js应用在运行时尝试删除/srv/dist/functions/next/BUILD_ID文件,自然触发了EROFS只读文件系统错误。

问题根源

Next.js在生产模式下会自动检查并更新BUILD_ID文件(用来验证当前构建版本的一致性),但GAE的核心部署目录/srv是完全只读的,不允许任何写入或删除操作,这就是报错的核心原因。

解决方案

我们需要让Next.js使用GAE中唯一可写的/tmp目录来存储它需要修改的运行时文件,具体步骤如下:

1. 修改自定义server.js的Next配置

在你的server.js中,初始化Next应用时指定distDir为/tmp下的专属目录,让Next.js把需要读写的文件放在可写路径:

const next = require('next');
const express = require('express');

// 关键配置:指定Next.js使用/tmp下的可写目录存储构建相关文件
const nextApp = next({
  dev: process.env.NODE_ENV !== 'production',
  dir: './src/app', // 你的Next应用根目录
  distDir: '/tmp/next-build' // 指向GAE唯一可写的tmp目录
});

const handle = nextApp.getRequestHandler();

nextApp.prepare().then(() => {
  const app = express();
  // ... 你的其他server配置(路由、中间件等)
  
  app.get('*', (req, res) => {
    return handle(req, res);
  });

  app.listen(process.env.PORT || 3000, (err) => {
    if (err) throw err;
    console.log('> Ready on http://localhost:3000');
  });
});

2. 更新启动脚本,复制构建文件到/tmp

你是本地构建好.next目录后再部署到GAE的,所以需要在应用启动时,把只读目录下的构建文件复制到/tmp/next-build(也就是刚才指定的distDir)。修改package.json中的start脚本:

"scripts": {
  // ... 其他脚本保持不变
  "start": "cd \"src/app/\" && cp -r .next /tmp/next-build && NODE_ENV=production node server.js"
}

这个命令会先把本地构建好的.next目录完整复制到可写的/tmp/next-build,再启动自定义server,这样Next.js运行时就能正常读写所需文件了。

3. 验证部署流程

确保你的deploy:gae脚本还是先执行本地构建再部署:

"deploy:gae": "npm run build-next; gcloud app deploy"

同时确认你的.gcloudignore没有排除.next目录(你的配置里确实没排除,这点没问题),这样构建好的.next目录会被正常上传到GAE。

额外检查点

  • 你的app.yaml指定了runtime: nodejs10,属于GAE标准环境,这个方案完全适配;如果是灵活环境,虽然有更多可写目录,但这个方法依然有效。
  • 如果你的Next.js应用还有其他需要写入文件的逻辑(比如缓存、临时文件),也要确保它们都指向/tmp目录,这是GAE标准环境唯一的可写路径。

按照这些步骤修改后,重新部署应该就能解决只读文件系统的错误了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:02:37