Heroku部署Node.js/Express API遇R10错误:PORT变量获取失败
我搭建了一个Node.js/Express Web API,本地运行正常,但部署到Heroku时出现如下错误:
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
我的index.js代码如下:
app.listen(process.env.PORT || 3000, () => { console.log(`app running on ${process.env.PORT}`); });
.env文件内容:
PORT=3000
我已在Heroku的Settings>Config Vars中配置了PORT变量,但问题仍未解决。查看Heroku应用日志发现,listen()方法的回调输出如下:
2022-07-15T20:06:19.268954+00:00 app[web.1]: app running on undefined
2022-07-15T20:06:20.230943+00:00 app[web.1]: connected to db
其中“connected to db”来自MongoDB连接,应用能正常从.env文件获取MongoDB凭证,但为何无法获取PORT变量,返回undefined?
问题分析与解决办法
1. 日志输出的误导性
你代码里用了process.env.PORT || 3000,这意味着当process.env.PORT不存在时,会回退到3000端口启动。但日志打印的还是process.env.PORT,所以即使实际用了3000,日志依然会显示undefined。不过Heroku不允许绑定固定端口,必须用它动态分配的$PORT,这才是R10超时错误的核心原因。
2. .env文件在Heroku上不生效
Heroku不会读取你的本地.env文件,哪怕提交到代码仓库也没用。而且你在Config Vars里手动设置的PORT会被Heroku强制覆盖——Heroku会自动注入自己的$PORT环境变量,你手动配置的端口值会被忽略。
3. 关键修复步骤
- 修正日志与端口逻辑:把端口赋值给变量,确保日志打印实际使用的端口,同时保留本地开发的回退:
const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`app running on ${port}`); }); - 限制dotenv的加载环境:如果本地用了
dotenv,要确保只在开发环境加载,避免生产环境(Heroku)读取本地配置:if (process.env.NODE_ENV !== 'production') { require('dotenv').config(); } - 检查Procfile配置:确保项目根目录的
Procfile内容为web: node index.js(替换为你的实际入口文件名),Heroku依赖这个文件识别Web启动命令。 - 忽略.env文件:把
.env加入.gitignore,既避免敏感信息泄露,也防止Heroku读取到本地端口配置。
4. 验证修复
重新部署后查看Heroku日志,如果看到类似app running on 54321的随机端口输出,说明已正确绑定Heroku分配的端口,R10超时错误会随之消失。
内容的提问来源于stack exchange,提问作者yasinkuyuk

