【问题标题】:Node.js express app keep crashing on herokuNode.js express 应用程序在 heroku 上不断崩溃
【发布时间】:2017-10-23 12:20:57
【问题描述】:

我在 heroku 上推送了一个相当简单的 node.js express 应用程序,但无法使其工作。它立即崩溃。 heroku tail --logs 给我:

2017-05-23T04:43:08.156660+00:00 app[api]: Scaled to web@1:Free worker@0:Free by user jp@yetie.fr
2017-05-23T04:43:24.388293+00:00 heroku[web.1]: Starting process with command `: node server.js`
2017-05-23T04:43:26.207926+00:00 heroku[web.1]: Process exited with status 0
2017-05-23T04:43:26.220393+00:00 heroku[web.1]: State changed from starting to crashed
2017-05-23T04:43:26.221461+00:00 heroku[web.1]: State changed from crashed to starting
2017-05-23T04:43:43.343050+00:00 heroku[web.1]: Starting process with command `: node server.js`
2017-05-23T04:43:44.751608+00:00 heroku[web.1]: Process exited with status 0
2017-05-23T04:43:44.762870+00:00 heroku[web.1]: State changed from starting to crashed
2017-05-23T04:43:46.400260+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=yetie.herokuapp.com request_id=d7913d1e-64ab-497b-a59d-fda9454d6e69 fwd="81.56.46.53" dyno= connect= service= status=503 bytes= protocol=https
2017-05-23T04:43:46.899099+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=yetie.herokuapp.com request_id=1fdc61fb-eebe-40a2-8b0a-a71b09f7ff10 fwd="81.56.46.53" dyno= connect= service= status=503 bytes= protocol=https

我有一个 Procfile,其中包含:

web : node server.js
worker: node workers/match.js

工人,按预期运行。 server.js 看起来像这样:

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

app.use(express.static(__dirname + '/testheroku'));

app.listen(process.env.PORT || 8080, function(){
  console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env);
});

在 /testheroku 目录中有一个“hello world”html 文件。

当我使用heroku local web 在本地运行它时,它可以工作,当我通过使用heroku run bash 然后node server.js 连接到heroku dyno 运行它,然后执行wget http://localhost:xxxx 它正确地获得“hello world”html 文件。

但是当我尝试访问 heroku 在构建应用程序时提供给我的 url 时,我得到了上面的崩溃日志。

Node 和 npm 版本在本地和 heroku 上是相同的:

node --version => v6.10.3
npm --version => 3.10.10

如果需要,我可能会包含 package.json 文件,但它相当长(基于更复杂的 angular2 应用程序)并且它可以在本地和 heroku 上正确编译。当我设法通过连接到 dyno thru bash 来运行 node server.js 时,我怀疑问题应该存在。

我在 stackoveflow 或 elswere 上找到的大多数答案都暗示了端口问题,并使用了 app.listen(process.env.PORT || 8080) 技巧,我这样做了。那么我在这里缺少什么?

【问题讨论】:

    标签: node.js express heroku


    【解决方案1】:

    确保您实际上可以使用 npm start 启动您的应用,并且它不会退出,就像在 Heroku 上那样。

    从日志看来,您的应用程序从状态 0 开始大约 2 秒后退出,这通常是进程正常退出的情况,因为没有更多的事件侦听器,但有时它可能是由其他问题引起的,尤其是当您的异常被自动捕获并且您没有看到正确的上下文时。

    还要确保您的应用不依赖于您的 package.json 中未包含的任何全局安装的依赖项。确保 Heroku 完成所有所需的安装和构建步骤。确保您可以将代码复制到一个新目录并使用npm install && npm start 运行它。

    我会改变这个:

    app.listen(process.env.PORT || 8080, function(){
      console.log("Express server listening on port %d in %s mode", this.address().port, app.settings.env);
    });
    

    到这里:

    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log('Express server listening on port', port)
    });
    

    确保它不会因为您要访问的所有变量而崩溃。

    如果还是不行,看看我在 GitHub 上的演示:

    它还使用express.static 并且已知可以在 Heroku 上工作 - 带有部署到 Heroku 按钮:

    比普通 Heroku 应用程序要求更严格。

    查看该项目中的 package.json、server.js 和 app.json。

    您应该能够拥有一个最小的 server.js 文件:

    'use strict';
    
    const path = require('path');
    const express = require('express');
    const http = require('http');
    
    const app = express();
    const server = http.Server(app);
    
    const port = process.env.PORT || 8080;
    
    app.use('/', express.static(path.join(__dirname, 'testheroku')));
    
    server.listen(port, () => {
      console.log(`Listening on http://localhost:${port}/`);
    });
    

    或者没有直接使用http 模块:

    'use strict';
    
    const path = require('path');
    const app = require('express')();
    
    const port = process.env.PORT || 8080;
    
    app.use('/', express.static(path.join(__dirname, 'testheroku')));
    
    app.listen(port, () => {
      console.log(`Listening on http://localhost:${port}/`);
    });
    

    但你的 package.json 包含一个启动脚本也很重要:

      "scripts": {
        "start": "node server.js"
      },
    

    【讨论】:

    • 搞定了! Procfile 会覆盖 package.json 中的启动脚本。从 Procfile 中删除了行 web: node server.js。让工人就行了。 Heroku 仍然发现了两种进程类型。一个web: npm start 和一个worker: node workers/match.js 现在即使 npm start 执行与从 Procfile 中删除的行完全相同的事情,它也可以工作。保持我的 server.js 文件不变。
    【解决方案2】:

    您可以这样做的另一种方法是:

    app.set("port", process.env.PORT || 3000);
    app.set("host", process.env.HOST || "localhost");
    
    app.listen(app.get("port"), function() {
      console.log(
       "%s server listening at http://%s:%s",
        process.env.NODE_ENV,
       app.get("host"),
       app.get("port")
      );
    });
    

    【讨论】:

      猜你喜欢
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2018-03-12
      • 2014-09-10
      • 1970-01-01
      • 2018-04-03
      相关资源
      最近更新 更多