Lỗi Heroku + node.js (Quá trình web không thể liên kết với $ PORT trong vòng 60 giây sau khi khởi chạy)


447

Tôi có ứng dụng node.js đầu tiên của mình (chạy tốt cục bộ) - nhưng tôi không thể triển khai nó thông qua heroku (lần đầu tiên cũng là w / heroku). Mã dưới đây. Vì vậy, tôi không cho phép tôi viết quá nhiều mã, vì vậy tôi chỉ nói rằng việc chạy mã cục bộ cũng như trong mạng của tôi cho thấy không có vấn đề gì.

 var http = require('http');
 var fs = require('fs');
 var path = require('path');

 http.createServer(function (request, response) {

    console.log('request starting for ');
    console.log(request);

    var filePath = '.' + request.url;
    if (filePath == './')
        filePath = './index.html';

    console.log(filePath);
    var extname = path.extname(filePath);
    var contentType = 'text/html';
    switch (extname) {
        case '.js':
            contentType = 'text/javascript';
            break;
        case '.css':
            contentType = 'text/css';
            break;
    }

    path.exists(filePath, function(exists) {

        if (exists) {
            fs.readFile(filePath, function(error, content) {
                if (error) {
                    response.writeHead(500);
                    response.end();
                }
                else {
                    response.writeHead(200, { 'Content-Type': contentType });
                    response.end(content, 'utf-8');
                }
            });
        }
        else {
            response.writeHead(404);
            response.end();
        }
    });

 }).listen(5000);

 console.log('Server running at http://127.0.0.1:5000/');

Bất kỳ ý tưởng ?


Bạn có thể gửi mã của bạn ở đây? Tốt nhất là phần .listen () nếu bạn đang khởi động máy chủ http
Benjamin Gruenbaum

Câu trả lời:


987

Heroku tự động gán cho ứng dụng của bạn một cổng, vì vậy bạn không thể đặt cổng thành một số cố định. Heroku thêm cổng vào env, vì vậy bạn có thể kéo nó từ đó. Chuyển nghe của bạn để này:

.listen(process.env.PORT || 5000)

Bằng cách đó, nó vẫn sẽ nghe cổng 5000 khi bạn kiểm tra cục bộ, nhưng nó cũng sẽ hoạt động trên Heroku.

Bạn có thể xem tài liệu Heroku trên Node.js tại đây .


96
quan trọng là bạn sử dụng process.env.PORT chứ không phải process.env.port.
gprasant

xinh đẹp! làm việc cho tôi với mô-đun 'websocket'.
philx_x

1
Cảm ơn vì đã tiết kiệm thời gian của tôi.
allsoft


2
Cảm ơn, làm việc cho tôi cũng. Tôi ngạc nhiên điều này đã không được làm rõ hơn trong các tài liệu Heroku
sidarcy

34

Lỗi xảy ra khi Heroku không thể liên kết cổng hoặc tên máy chủ tại server.listen(port, [host], [backlog], [callback]).

Những gì Heroku yêu cầu là .listen(process.env.PORT)hoặc.listen(process.env.PORT, '0.0.0.0')

Vì vậy, tổng quát hơn, để hỗ trợ các môi trường khác, hãy sử dụng:

var server_port = process.env.YOUR_PORT || process.env.PORT || 80;
var server_host = process.env.YOUR_HOST || '0.0.0.0';
server.listen(server_port, server_host, function() {
    console.log('Listening on port %d', server_port);
});

6
Với cuộc gọi sau: app.listen (serverPort, "localhost", function (err) {Heroku đã thất bại. Chuyển đổi "localhost" thành "0.0.0.0". Cảm ơn!
pubsy

31

Điều đáng nói là nếu mã của bạn không chỉ định một cổng, thì đó không nên là một webquá trình và có lẽ nên là một workerquá trình thay thế.

Vì vậy, thay đổi Procfileđể đọc (với lệnh cụ thể của bạn được điền vào):

worker: YOUR_COMMAND

và sau đó cũng chạy trên CLI:

$ heroku scale worker=1


1
Tôi gặp vấn đề tương tự Tôi có thể giải quyết vấn đề bằng cách thay thế 'localhost' bằng IP là '0.0.0.0'
Damith Asanka

2
Tôi đang chạy bot Discord trên Heroku và điều này đã khiến tôi phải lo lắng. Slack, Hipchat, vv các bot có thể có vấn đề tương tự.
Skylar

1
Nếu bạn đi theo tuyến đường này, hãy đảm bảo chuyển đến tab Tài nguyên, tắt quy trình web và bật quy trình công nhân. Theo cách đó Heroku sẽ không mong đợi một ràng buộc cổng.
Isaac Lyman

1
Ohh cảm ơn bạn rất nhiều. Tôi đã cố gắng để tìm kiếm điều này. Tôi không có ý tưởng về web và các ứng dụng worker khác nhau ở Heroku về mặt Procfile. Điều đáng nói là họ cần tôi thêm một startkịch bản vào trongpackage.json
Rishav

1
Trong trường hợp của tôi, tôi đã thay đổi Procfile từ web thành worker. Nó đã làm việc!! Thkns
rodrigorf

27

Tôi đã gặp vấn đề tương tự trong khi sử dụng dự án tạo góc đầy đủ của yeoman và loại bỏ tham số IP làm việc cho tôi.

Tôi đã thay thế mã này

server.listen(config.port, config.ip, function () {
  console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

với

server.listen(config.port, function () {
  console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

25

Đối với những người đi qua cả cổng và máy chủ, hãy nhớ rằng Heroku sẽ không liên kết localhost .

Bạn phải vượt qua 0.0.0.0 cho chủ nhà.

Ngay cả khi bạn đang sử dụng đúng cổng. Chúng tôi đã phải thực hiện điều chỉnh này:

# port (as described above) and host are both wrong
const host = 'localhost';
const port = 3000;

# use alternate localhost and the port Heroku assigns to $PORT
const host = '0.0.0.0';
const port = process.env.PORT || 3000;

Sau đó, bạn có thể khởi động máy chủ, như thường lệ:

app.listen(port, host, function() {
  console.log("Server started.......");
});

Bạn có thể xem thêm chi tiết tại đây: https://help.heroku.com/P1AVPANS/why-is-my-node-js-app-crashing-with-an-r10-error


3
Câu trả lời này không chỉ đầy đủ hơn, mà là câu hỏi duy nhất nhắm đến hai vấn đề có thể xảy ra. Trong trường hợp của tôi, cấu hình cổng là chính xác, nhưng không phải là địa chỉ nghe. Đây phải là câu trả lời được chấp nhận.
Danielo515

Trong trường hợp của tôi, nó hoạt động khi tôi thay đổi như bên dưới const port = 3000;để const port = process.env.PORT || 3000; nó hoạt động trên heroku
vpgodara

điều duy nhất thực sự có hiệu quả với tôi, cảm ơn
Ibrahim Mohammed

10

Trong trường hợp của tôi, tôi đã sử dụng ví dụ từ https://hapijs.com/

Để khắc phục sự cố tôi đã thay thế

server.connection({ 
    host: 'localhost', 
    port: 8000 
});

với

server.connection({
    port: process.env.PORT || 3000 
});

và đối với những người sử dụng chỉ định process.env.PORTchính xác, nhưng để lại trong hostparam: bạn không thể :) xem tại đây: stackoverflow.com/a/34956330/626369
Dominick

3

Tôi đã có cùng một vấn đề và thay đổi cổng nghe của tôi từ 3000 thành (process.env.PORT || 5000) đã giải quyết vấn đề !!


2

Trong trường hợp của tôi, tôi đã sử dụng Babel với plugin babel-plugin-Transform-inline-môi trường-biến . Rõ ràng, Heroku không đặt biến PORT env khi thực hiện triển khai, do đó process.env.PORTsẽ được thay thế undefinedvà mã của bạn sẽ chuyển sang cổng phát triển mà Heroku không biết gì.


1

Các bước dưới đây đã giải quyết giải pháp của tôi:

Chỉnh sửa gói.json như:

...
"engines": {
"node": "5.0.0",
"npm": "4.6.1"
},
...

Server.js là:

...
var port = process.env.PORT || 3000;
app.listen(port, "0.0.0.0", function() {
console.log("Listening on Port 3000");
});
...

Trong trường hợp của tôi, tôi đã lấy ra một phần của package.json. Tôi tin rằng cập nhật nó cũng nên giải quyết vấn đề này.
Đánh dấu

1

Tôi gặp vấn đề tương tự vì tôi không định nghĩa Procfile. Cam kết một tệp văn bản vào thư mục gốc của ứng dụng có tên Procfile mà không cần phần mở rộng tệp. Tệp này cho Heroku biết lệnh nào sẽ chạy để khởi động ứng dụng của bạn.
web: node app.js


Cảm ơn, tôi quên làm điều này. Không có tệp này, heroku chỉ bỏ qua các tệp hoàn toàn.
Vladimir Despotovic

0

Tôi gặp vấn đề tương tự Tôi có thể giải quyết vấn đề bằng cách thay thế 'localhost' bằng IP là '0.0.0.0'


0

Một số cố định không thể được đặt cho cổng, heroku gán nó một cách linh hoạt bằng cách sử dụng process.env.PORT. Nhưng bạn có thể thêm cả hai, như thế này process.env.PORT || 5000. Heroku sẽ sử dụng cái đầu tiên và localhost của bạn sẽ sử dụng cái thứ hai.

Bạn thậm chí có thể thêm chức năng gọi lại của bạn. Nhìn vào mã dưới đây

app.listen(process.env.PORT || 5000, function() {
    console.log("Server started.......");
});

0

Trong tất cả các giải pháp tôi đã thử không có ai làm việc như mong đợi, tôi mặc định nghiên cứu heroku theo cách .env File nên duy trì quy ước PORT, process.env.PORT, heroku theo mặc định sẽ tìm PORT PORT.

Hủy bỏ mọi đổi tên, chẳng hạn như APP_PORT = thay vào đó sử dụng PORT = trong tệp env của bạn.


0

Từ quy trình bash heroku, chuyển giá trị $ PORT cho ứng dụng nút của bạn bằng cách sử dụng trình phân tích cú pháp tùy chọn như yargs.

Dưới đây là một ví dụ về cách bạn có thể làm điều đó. Trên đối tượng script, bên trong gói.json, thêm phương thức bắt đầu "nút máy chủ - cổng $ PORT".

Trong tệp máy chủ của bạn, sử dụng yargs để lấy giá trị từ tùy chọn cổng (--port $ PORT) của phương thức start:

const argv = require('yargs').argv;
const app = require('express')();

const port = argv.port || 8081;

app.listen(argv.port, ()=>{
    console.log('Probably listening to heroku $PORT now ', argv.port); // unless $PORT is undefined, in which case you're listening to 8081.
});

Bây giờ khi ứng dụng của bạn khởi động, nó sẽ liên kết với giá trị được đặt động của $ PORT.


0

Nếu, giống như tôi, bạn đang định cấu hình Heroku để chạy tập lệnh từ package.jsontệp của bạn khi triển khai, hãy đảm bảo rằng bạn chưa mã hóa giá trị của PORTtập lệnh đó! Nếu bạn làm thế, bạn sẽ kết thúc giống tôi và dành một giờ cố gắng để tìm hiểu tại sao bạn lại gặp phải lỗi này.


0

Tôi đã có cùng một vấn đề nhưng với máy chủ tốc độ và nhanh. Giải pháp từ đây :

Việc xem xét đặc biệt duy nhất cần được thực hiện là cho phép heroku chọn cổng mà máy chủ được triển khai. Nếu không, có thể có lỗi, chẳng hạn như thời gian chờ yêu cầu.

Để định cấu hình máy chủ apollo để sử dụng một cổng được xác định bởi Heroku khi chạy, chức năng nghe trong tệp thiết lập của bạn có thể được gọi với một cổng được xác định bởi biến môi trường PORT:

> server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => { 
> console.log(`Server ready at ${url}`); });

0

Trong trường hợp của tôi, tôi đã có hai vấn đề ...

1) hoàn toàn không có người nghe vì chạy ứng dụng từ một tệp nhập khác và tập lệnh chạy này đã bị xóa khỏi gói "script"

nhập mô tả hình ảnh ở đây

2) Sự cố phân biệt chữ hoa chữ thường với 'Sequelize' thay vì 'sequelize'

nhập mô tả hình ảnh ở đây


0

Tôi đã từng gặp vấn đề tương tự. Cuối cùng, tôi nhận ra rằng tôi không cần số cổng trong điểm cuối yêu cầu. (vì vậy điểm cuối là https: //...herokuapp.com chứ không phải https: //...herokuapp.com: 5000 ).

Cuộc gọi nghe () có thể không có máy chủ và cuộc gọi lại: server.listen (5000);


Bạn không cần số cổng trong URL nếu bạn sử dụng cổng mặc định. Vậy làm thế nào để giải quyết vấn đề?
RalfFriedl

0

Trong trường hợp của tôi, cả cổng và máy chủ đều không phải là vấn đề. Index.js của chúng tôi được chia thành 2 tệp server.js

//server.js
const express = require('express')
const path = require('path')

const app = express()

app.use(express.static(path.resolve(__dirname, 'public')));
// and all the other stuff
module.exports = app

//app.js
const app = require('./server');
const port = process.env.PORT || 3000;
app.listen(port, '0.0.0.0', () => {
    console.log('Server is running s on port: ' + port)
});

từ pack.json, chúng tôi đã chạy nút app.js

Rõ ràng đó là vấn đề. Khi tôi kết hợp cả hai thành một tệp, ứng dụng heroku được triển khai như mong đợi.

Hy vọng nó sẽ giúp được ai đó vì tôi không tìm thấy ai gặp phải vấn đề này


0

Tôi sử dụng ReactJs, Nếu bạn muốn tải lên heroku, hãy thêm cái này vào webpack.config.js của bạn

Bởi vì nếu không thêm bạn sẽ có lỗi

Lỗi R10 (Hết thời gian khởi động) -> Quá trình web không thể liên kết với $ PORT trong vòng 60 giây kể từ khi khởi chạy

//webpack.config.js add code like that

const HtmlWebPackPlugin = require(“html-webpack-plugin”);
const MiniCssExtractPlugin = require(“mini-css-extract-plugin”);
var server_port = process.env.YOUR_PORT || process.env.PORT || 5000;
var server_host = process.env.YOUR_HOST || 0.0.0.0’;

module.exports = {
 module: {
 rules: [
 {
 test: /\.js$/,
 exclude: /node_modules/,
 use: {
 loader: babel-loader
 }
 },
 {
 test: /\.css$/,
 use: [MiniCssExtractPlugin.loader, css-loader”]
 }
 ]
 },
 devServer: {
 disableHostCheck: true,
 contentBase: ‘./dist’,
 compress: true,
 inline: true,
 port:server_port,
 host:server_host

},
 plugins: [
 new HtmlWebPackPlugin({
 template: “./src/index.html”,
 filename: index.html
 }),
 new MiniCssExtractPlugin({
 filename: “[name].css”,
 chunkFilename: “[id].css
 })
 ]
};

0

Tín dụng cho: gprasant

Tôi chỉ muốn đăng lại vì câu trả lời này đã khắc phục vấn đề của tôi. Vấn đề của tôi là khi triển khai lên heroku tôi đã gặp lỗi "Quá trình web không thể liên kết với $ PORT trong vòng 60 giây kể từ khi khởi chạy" khi chạy "nhật ký heroku - đuôi" trong thiết bị đầu cuối. NHƯNG ứng dụng sẽ chạy như mong đợi khi tôi chạy máy chủ cục bộ.

Tôi đã có cái này trong tệp index.js (tệp máy chủ)

const PORT = process.env.port || 4000

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`)
})

Nhưng nên có cái này

const PORT = process.env.PORT || 4000

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`)
})

Sử dụng process.env.PORT không process.env.port !!!! cảng! = CẢNG !!! (chắc chắn)

Tín dụng cho: gprasant

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.