I'm working on a Hapi server for a ReactJS app but when I try to deploy to Heroku, I get the R10 error "Failed to bind to $PORT within 60 seconds of launch". What is going on? I'm using process.env.PORT. I also tried parseInt() around it. Also tried disabling varying packages. The build is successful always.
In the Heroku logs, I see the console log from the index.js ("Hapi running on ...") but then the R10 error shows up and the server restarts, then crashes.
==> 🌎 Hapi Production Server (API) is listening on http://localhost:14316 2016-01-22T15:10:33.947571+00:00 heroku[web.1]: Stopping process with SIGKILL 2016-01-22T15:10:33.947571+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch 2016-01-22T15:10:34.737554+00:00 heroku[web.1]: State changed from starting to crashed 2016-01-22T15:10:34.724233+00:00 heroku[web.1]: Process exited with status 137
This all runs fine locally when I run with NODE_ENV=production
src/server.js
import Hapi from 'hapi';
import Inert from 'inert';
import jwt from 'hapi-auth-jwt2';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { RoutingContext, match } from 'react-router';
import { Provider } from 'react-redux';
import createRoutes from './routes';
import configureStore from './store/configureStore';
import Html from './Html';
const PROTOCOL = 'http://';
const SERVER_HOST = process.env.HOST || 'localhost';
const SERVER_PORT = process.env.PORT || 3000;
const API_HOST = process.env.API_HOST || 'localhost';
const API_PORT = process.env.API_PORT || 8000;
export default function(callback) {
const server = new Hapi.Server();
server.connection({
host: SERVER_HOST,
port: SERVER_PORT,
labels: ['api'],
// routes: {
// cors: {
// origin: [PROTOCOL + API_HOST + ':' + API_PORT]
// }
// }
});
server.connections[0].name = 'API';
server.register([
{ register: Inert },
{ register: jwt },
// {
// register: api,
// routes: {
// prefix: '/api'
// }
// }
], (err) => {
if(err) {
console.error('ERROR:', err)
throw err;
}
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: 'static'
}
}
});
server.ext('onPreResponse', (request, reply) => {
if (typeof request.response.statusCode !== 'undefined') {
return reply.continue();
}
const assets = {
javascript: {
main: '/dist/bundle.js'
}
};
const store = configureStore();
const routes = createRoutes(store);
// this gets called if server side rendering/routing has problems and errors
function hydrateOnClient() {
reply('<!doctype html>\n' +
renderToString(<Html assets={assets} store={store} />)).code(500);
}
match({ routes, location: request.path }, (error, redirectLocation, renderProps) => {
if (redirectLocation) {
res.redirect(301, redirectLocation.pathname + redirectLocation.search)
} else if (error) {
console.error('ROUTER ERROR:', error) // eslint-disable-line no-console
hydrateOnClient();
} else if (!renderProps) {
// in some cases this would act as a 404 but that should be handled in the routes
hydrateOnClient();
} else {
const component = (
<Provider store={store}>
<RoutingContext {...renderProps} />
</Provider>
);
reply('<!doctype html>\n' +
renderToString(<Html assets={assets} component={component} store={store} />)
);
}
});
});
});
return server.start((err) => {
if(err) {
console.log(err);
throw err;
}
callback(server)
});
}
index.js
require('babel-core/register');
global.__DEVELOPMENT__ = process.env.NODE_ENV !== 'production';
global.__SERVER__ = true;
global.__CLIENT__ = false;
const server = require('./src/server');
server(server => {
for (var key of Object.keys(server.connections)) {
console.info('==> 🌎 Hapi Production Server (' + server.connections[key].name + ') is listening on', server.connections[key].info.uri);
}
});
Heroku expects a web application to bind its HTTP server to the port defined by the $PORT environment variable. Many frameworks default to port 8080, but can be configured to use an environment variable instead.
Heroku sets the PORT variable that you are supposed to bind, and listens on tcp/80.
PORT || 3000 means: process. env. PORT means the PORT number you manually set. 3000 is the default port . If you havent set it manually then it will listen to 3000.
process.env.HOST
was undefined on Heroku, and for some reason it didn't like localhost
as the host, which caused the issue.
I simply removed the host var all together, so connection looks like:
server.connection({
port: process.env.PORT || 3000,
labels: ['api'],
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With