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); }});