Heroku部署MERN应用服务端报H10错误崩溃无法运行
本地运行正常但Heroku报H10进程崩溃,是几个部署配置和代码逻辑的常见问题导致的,按以下步骤逐一修复即可:
核心问题排查与修复
问题1:MongoDB连接无错误捕获+端口绑定时序错误
你当前的代码是同时发起数据库连接、启动端口监听,没有对数据库连接失败做异常捕获。一旦数据库连不上会直接抛出未捕获异常导致进程退出,Heroku会直接判定为H10崩溃;同时如果数据库连接耗时过长,还可能出现Heroku等待端口绑定超时的问题。注意:替换代码时要删掉文件里原来单独写的
app.listen调用和mongoose.connection.on('connected')监听逻辑,不要重复执行端口绑定。
把index.js里的数据库连接和端口监听部分替换为以下代码:import express from "express"; import bodyParser from 'body-parser'; import mongoose from 'mongoose'; import cors from 'cors'; import postRoutes from './routes/posts.js'; import dotenv from 'dotenv'; const app = express(); dotenv.config(); app.use(bodyParser.json({ limit: "30mb", extended: true })); app.use(bodyParser.urlencoded({ limit: "30mb", extended: true })); app.use(cors()); app.use('/posts', postRoutes); app.get('/', (req,res) => { res.send('Expense Tracker API working') }) const PORT = process.env.PORT || 5000; const CONNECTION_URL = process.env.CONNECTION_URL || "mongodb+srv://expensetracker:expensetracker1@cluster0.d5vlkxz.mongodb.net/?retryWrites=true&w=majority"; // 等数据库连接成功后再绑定端口,连接失败直接打印错误退出 mongoose.connect(CONNECTION_URL) .then(() => { app.listen(PORT, () => { console.log(`Server running on port ${PORT}, database connected`); }) }) .catch((err) => { console.log("Startup failed:", err.message); process.exit(1); });问题2:MongoDB Atlas IP白名单未放行Heroku访问
Heroku的服务出口IP是动态变化的,如果你MongoDB Atlas的网络访问配置只加了本地IP,Heroku永远连不上数据库,直接导致启动失败。
操作步骤:- 登录MongoDB Atlas控制台进入对应集群
- 找到Network Access配置页
- 添加IP地址
0.0.0.0/0(允许所有IP访问,适配Heroku动态IP场景),保存配置等待生效。
问题3:未指定Node.js运行版本导致兼容问题
你项目用了ES Module规范(package.json里配置了"type": "module"),如果Heroku默认分配的Node.js版本过低(低于14.x),会直接报语法错误导致启动崩溃。
先在本地终端执行node -v查看你本地运行正常的Node版本,然后在package.json里添加engines字段指定版本,示例:{ "name": "server", "version": "1.0.0", "main": "index.js", "type": "module", "engines": { "node": "16.x" // 替换为你本地实际的Node大版本即可,比如18.x }, "scripts": { "start": "node index.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "body-parser": "^1.20.0", "cors": "^2.8.5", "dotenv": "^16.0.1", "express": "^4.18.1", "mongoose": "^6.3.6", "nodemon": "^2.0.16" }, "description": "" }问题4:Procfile配置或存放位置错误
你当前Procfile里的内容web: node index.js是正确的,但要确认两个点:- Procfile必须放在项目根目录,不能放在server等子文件夹里
- 文件名必须是首字母大写的
Procfile,没有任何后缀名,不要存成Procfile.txt这类带格式后缀的文件。
后续排查技巧
修改完以上配置重新部署后,如果还是报错,直接在本地项目目录执行heroku logs --tail查看实时启动日志,日志会明确打印具体的崩溃原因(比如依赖缺失、环境变量配置错误、数据库权限不对等),不用只盯着H10通用错误码猜问题。
另外注意:你现在把开发依赖nodemon放在了生产依赖里,不会直接导致启动失败,但会增大部署包体积,后续可以把它移到devDependencies里优化。
内容的提问来源于stack exchange,提问作者MessyMonkey

